How create HyperLink to local bookmark with JS? (href=#bookmarkname)

Hi, friends. I am unable to create a valid bookmark link in the document.

ApiRange.AddHyperlink(sLink, sScreenTipText) → { ApiHyperlink | null }

with sLink = ‘#bookmarkname’ not create correct link.

When clicking on this link, the cursor does not move to the bookmark

Hello @XOMRKOB

I’m afraid AddHyperlink is not a suitable option here as it requires an actual link to work.

If I understand your goal correctly, you want to have a link to a bookmark in the document when clicking which cursor moves to the position of required bookmark. For that you can create a cross-reference link to the bookmark with method AddBookmarkCrossRef.

1 Like

Спасибо, Константин.

I hope it helps.

Please note that official languages of this forum are English and Chinese.

Good afternoon. I am unable to add a cross-reference to a bookmark in my plugin. I want to create a cross-reference to a bookmark in the ContentControl element.

        const onAddCiteCC = async (_cc) => {
            const arrDocuments = [{
                "Props": {
                    "InternalId": _cc.InternalId,
                    "Inline": true
                },
                "Script": `
                    const cite = Api.CreateParagraph();
                    cite.AddText("[${_cc.Tag}]");
                    Api.GetDocument().InsertContent([cite], true, {KeepTextOnly: true});
                    cite.AddBookmarkCrossRef('text', "${_cc.Id}", true);
                    `

            }]
            this.executeMethod("InsertAndReplaceContentControls", [arrDocuments]);
        }

        const pastInTextButtonClickHandler = async (e) => {
            const article_id = e.target.getAttribute('data-article-id');
            const index = getArticleStringsFromLocalStorage()[article_id]['index']
            this.executeMethod('AddContentControl', [2, {"Id": article_id, "Tag": index, "Lock": 3}], onAddCiteCC);
        }

The AddBookmarkCrossRef method returns false.

My plugin should generate a bibliography. The links that I am trying to make should move the cursor to an item from the bibliography at the end of the document.

The reason for using ContentControl is the ability to edit references to the list of references when changing the sorting order.

Why doesn’t it work?

That is a good design, however, I cannot see how bookmark as added in your example. You are adding a paragraph into Content Control and trying to add cross-reference to it instead of adding it to a bookmark as the documentation on AddBookmarkCrossRef says:

BookmarkName - string - The name of the bookmark to be referred to (must be in the document).

So before creating a cross-ref you need to add a bookmark to the required position in the document.

Hi, Constantine. I added logging, for understanding. The bookmark exists in the document.

const onAddCiteCC = async (_cc) => {
            const arrDocuments = [{
                "Props": {
                    "InternalId": _cc.InternalId,
                    "Inline": true
                }, // //cite.AddText("[${_cc.Tag}]");
                "Script": `
                    const cite = Api.CreateParagraph();
                    const bookmarks = Api.GetDocument().GetAllBookmarksNames();
                    console.log('All bookmarks', bookmarks);
                    console.log('I need to add: ${_cc.Id}');
                    console.log(bookmarks[0] === "${_cc.Id}");
                    cite.AddText("[");
                    const isBookmarkAdded = cite.AddBookmarkCrossRef('text', "${_cc.Id}", true);
                    console.log('isBookmarkAdded', isBookmarkAdded);
                    cite.AddText("]");
                    Api.GetDocument().InsertContent([cite], true, {KeepTextOnly: true});
                    `

            }]
            this.executeMethod("InsertAndReplaceContentControls", [arrDocuments]);
        }

        const pastInTextButtonClickHandler = async (e) => {
            const article_id = e.target.getAttribute('data-article-id');
            const index = getArticleStringsFromLocalStorage()[article_id]['index']
            this.executeMethod('AddContentControl', [2, {"Id": article_id, "Tag": index, "Lock": 3}], onAddCiteCC);
        }

A function for creating a bibliography with bookmarks:

const onAddContentControl = (_cc) => {
                localStorage.setItem('pal-bibliography-id', _cc.InternalId)
                const arrDocuments = [{
                    "Props": {
                        "InternalId": _cc.InternalId,
                        "Appearance": 2
                    },
                    "Script": `
                        const cites = JSON.parse(localStorage.getItem('pal-articles-cites'));
                        const oDocument = Api.GetDocument();
                        const articlesStrings = cites['articles'];
                        const bg = Api.CreateParagraph();
                        oDocument.InsertContent([bg]);
                        const title = Api.CreateParagraph();
                        title.SetJc('center');
                        const oTextPr = oDocument.GetDefaultTextPr();
                        oTextPr.SetBold(true);
                        title.AddText('Библиография');
                        bg.InsertParagraph(title, 'before', true);
                        oTextPr.SetBold(false);
                        const keys = Object.keys(cites);
                        keys.map((key) => {
                           const cite = cites[key];
                           const end = cite.index.toString().length;
                           const oParagraph = Api.CreateParagraph();
                           oParagraph.AddText(cite.refer);
                           bg.InsertParagraph(oParagraph, 'before', true);
                           const oRange = oParagraph.GetRange(0,end);
                           oRange.AddBookmark(key);
                        });
                        `
                }]
                this.executeMethod("InsertAndReplaceContentControls", [arrDocuments], (_re) => {console.log(_re)});
            }

It seems impossible to insert a cross-reference to a bookmark in the Contentcontrol element.

It’s very sad.

I see, thanks. I think the problem is that AddBookmarkCrossRef can be inserted in the paragraph that is already exists in the document as it is stated in the method documentation:

Please note that this paragraph must be in the document.

Considering that, you are using InsertContent with isInline:true it does not actually create a new paragraph as insertion of paragraph into another paragraph is prohibited by the text document structure, hence there is no paragraph object is defined to add crossref.

The only workaround I’ve come up with is to use isInline:false (default value) to separate paragraphs to insert crossref and then “concatenate” current and following paragraphs using GetNext, GetPrevious methods after which next paragraph can be deleted with Delete method:

var oDocument = Api.GetDocument();
var oParagraph = Api.CreateParagraph();
oDocument.InsertContent([oParagraph]); // Not using 'isInline: true'
oParagraph.AddBookmarkCrossRef("text", "Bookmark3", true);
var oNextParagraph = oParagraph.GetNext();
var sText = oNextParagraph.GetText({"Numbering": true, "Math": true, "NewLineSeparator": "\r", "TabSymbol": "\t"});
var oPreviousParagraph = oNextParagraph.GetPrevious();
oPreviousParagraph.AddText(sText);
var sParaConcatenate = oPreviousParagraph.GetNext();
sParaConcatenate.Delete();

Certainly it is not an ideal solution but it works. I will additionally check other ways but for now this is most suitable workaround to InsertContent method.

Hello again @XOMRKOB

We have found out that method AddBookmarkCrossRef is acting incorrectly right now and because of that when used with InsertContent it does not actually create a link. The fix will be available in version 8.2.

Sorry for inconvenience.

1 Like