Implementation of Table of Contents and Edit Button

Hello, I don’t know if I am in the right place but I need some help with xWiki regarding the implementation of the Table of Contents and the Edit Button so both are visible simultaneously.

I suspect that when the Table of Contents moves with the page while scrolling, it covers the Edit Button and hides it. This doesn’t entirely make sense, because even when the Table of Contents is small, I still can’t see the Edit Button. (as seen in the below image)

Currently, the only solution I have found is to fix the Table of Contents at the top of the page so it doesn’t move while scrolling. This way, the Edit Button appears for each new heading. But this is not quite what I want.

In the below pictures you will see what I meant above, how the table looks while not being fixed in the above position and here is how the table scrolls, as you can see, there is no edit button:

Any suggestions on how to resolve this issue would be greatly appreciated. Thank you!

Hello, yes it’s right place!

Are you referring to some feature in XWiki or some custom code? Right now XWiki doesn’t have any automatic TOC and only provides a {{toc}} macro to be used in your page content.

Looking at your screenshots, are you sure this is about XWiki (https://xwiki.org)? :slight_smile:


Hello,
As far as I know, this is xWiki, is just customized for the company use, where I work for. In the image provided, I’ve covered some words as I’m unsure if they should be visible outside the company.

I am aware of the TOC feature and thought there might already be something implemented in xWiki for this. If that’s not an option, I am looking for some custom code. Here’s what I found by looking into the xWiki.js:

insertSectionEditLinks: function(container) {
      // Insert links only if enabled, in view mode and for documents not in xwiki/1.0 syntax
      if ( $xwiki.hasSectionEdit() && XWiki.docsyntax != "xwiki/1.0" && XWiki.contextaction == "view" && XWiki.hasEdit) {

          // Section count starts at one, not zero.
          var sectionCount = 1;

          container = $(container || 'body');
          container = container.id == 'xwikicontent' ? container : container.down('#xwikicontent');
          if (!container) {
            return;
          }
          // We can't use element.select() since it does not keep the order of the elements in the flow.
          var nodes = container.childNodes;

          // Only allow section editing for the specified depth level (2 by default)
          var headerPattern = new RegExp("H[1-" + $xwiki.getSectionEditingDepth() + "]");

          // For all non-generated headers insert a link in order to be able to edit the section.
          for (var i = 0; i < nodes.length; i++) {

              var node = $(nodes[i]);

              if (headerPattern.test(node.nodeName) && !node.classList.contains('wikigeneratedheader') &&
                      !node.down('a.edit_section')) {
                  var editSectionLink = document.createElement('a');
                  editSectionLink.className = 'edit_section';
                  // Show the section editing link only if the section heading is visible.
                  editSectionLink.toggle(node.visible() && !node.hasClassName('hidden'));
                  editSectionLink.setAttribute('role', 'button');
                  editSectionLink.title = $jsontool.serialize($services.localization.render('edit'));
                  editSectionLink.innerHTML = $jsontool.serialize($services.icon.renderHTML('pencil'));

                  var editSectionLinkLabel = document.createElement('span');
                  editSectionLinkLabel.className = 'sr-only';
                  editSectionLinkLabel.textContent = $jsontool.serialize($services.localization.render('edit'));
                  editSectionLink.appendChild(editSectionLinkLabel);

                  // Disable the section editing link if there's no Syntax Renderer for the current document's syntax
                  // because editing a section requires a Syntax Renderer.
                  if (!XWiki.hasRenderer) {
                      editSectionLink.className = editSectionLink.className + ' disabled';
                      editSectionLink.setAttribute('aria-disabled', 'true');
                      editSectionLink.setAttribute('tabindex', '-1');
                      editSectionLink.title = $jsontool.serialize($services.localization.render(
                        'platform.core.rendering.noRendererForSectionEdit'));
                      editSectionLink.href = '#' + (node.id || '');
                  } else {
                      // FIXME: Use the xwiki-meta module to get the form token when we switch to jQuery/RequireJS.
                      var formToken = document.documentElement.getAttribute('data-xwiki-form-token');
                      editSectionLink.href = window.docediturl + "?section=" + sectionCount + '&form_token=' + formToken;
                  }

                  node.appendChild(editSectionLink);
                  sectionCount++;
              }
          }
      }
  },

The current problem is that using the TOC and making the table scroll as I scroll down the page creates two HTML divs. The code contains this part:

container=$(container||'body');
container=container.id=='xwikicontent'?container:container.down('#xwikicontent');

This basically looks in the child container and only considers the first child, if I understand correctly, and tries to edit that specific one.

What I tried was going into the browser’s developer options. Both divs had the name xwikicontent, so I renamed the div of the table to a random name and called the function:

insertSectionEditLinks:function(container)

The edit button appeared, but when I clicked it, I couldn’t edit the page. Instead, it redirected me to a blank page where I could edit. The link of the edit button contained a weird token, and I don’t know where it comes from.

Unfortunately, I don’t have pictures to show more details because I did this some time ago, but I hope you understand my problem.
I hope there is a way to edit the JavaScript code to perhaps look into all the child classes, not just the first one. This might allow the edit button to work correctly.

I just tried on XWiki 16.5.0 with this content:

(% class="box floatinginfobox" %)
(((
Table of Contents

{{toc/}}
)))

= Chapter 1 =

text

== Chapter 1.1 ==

text

= Chapter 2 =

text

== Chapter 2.1 ==

text

and the section editing links are visible:

So to me it looks like the problem you have is related either to your content (how you display the table of contents on the right of the content) or your CSS.

1 Like

Hello, thank you for the answer!
What you have shown me is not exactly what I am looking for, as illustrated in this picture:


I want to be able to scroll down the page, and the table of contents should move while scrolling. As seen in the image, I am somewhere at the end of the page, and the table follows as I scroll. I tried what you suggested, but the table is not moving and remains in the same place, which is not what I want.
Here is the code of the page shown in the image:

(% class="col-xs-12 col-sm-8" %)
(((
= Test 1 =

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. 


== Test2 ==

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 

= Test 3 =

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 

== test 4 ==

aaaaaaaaaaaaaaaaaaaaaaaaaaa Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
)))

(% class="col-xs-12 col-sm-4" style="position: sticky; top: 5px" %)
(((
(% class="box" %)
(((
**Contents**

{{toc/}}
)))
)))

I don’t think we have such a feature by default in XWiki, at least I’m not aware of it. But I think it’s doable with some CSS.

1 Like

Do you have any idea on how to create such thing in CSS? I am not that great with it, that’s one of the main reasons of why I created such a post on this forum. :slight_smile:

Is here anybody who could help me?

Perhaps I can explain it a bit easier for you guys to really get my problem, the issue isn’t that the TOC covers the Edit Buttons, but rather that these buttons aren’t rendered at all due to the additional DIV introduced by the (% … %) syntax between the xwikicontent div and the actual content of the page.

Essentially, the problem is this (imagine + “code”):

((( 
= test =
)))

= test2 =

As you can see, the lower heading has an Edit Button, but the upper one doesn’t because it’s wrapped in an additional div.

We need to wrap these headings in divs to fix the table of contents. The question is whether we can somehow generate these buttons for the first heading as well, so that the backend can handle it.

This is done on purpose. The content is parsed in a syntax tree. Only top level sections in this tree are editable. If you wrap your section in a DIV then it’s not at the top level anymore. When you edit a section (alone) the server-side needs to be able to extract the content of that section and then inject / replace it back on save. ATM it does this only for top level sections.

Hope this helps,
Marius

Oh I see, thank you very much.