Page 1 of 1

[javascript] determine which row is selected in dialog "hier_list_box"

Posted: Tue Nov 12, 2024 10:33 pm
by Mathew
When making custom dialog boxes through app.execDialog(), the type: "hier_list_box" seems like it could be very useful except: I can't see a way to find/set if parent elements are selected. Is there a way or some clever workaround?

For example, I've pasted a test script below that gets all the bookmarks in a pdf, and outputs to the console which row is selected. This is a screen capture of the bookmarks pane itself:
image.png
Running the script, I get a dialog listing the elements, but if I click on the row "Getting Started with Acrobat JavaScript", I can't find any way to know that row was selected:
image(1).png

Code: Select all

// using hierarchical list

function showBookmarks(doc) {
    const bkmDia = {
        // pointer for bookmarks
        bkm: [],
        
        initialize (dialog) {
            dialog.load({ sub1: this.loadHier( this.bkm )});
        },
        
        commit () {
        },
        
        sub1(dialog) {
            const ix = this.getIndex(dialog.store().sub1);
            console.println('Selected item: ' + ix);
            if (undefined === ix) console.println('Parent item selected, so no row information');
        },
        // returns the index number of the first item with positive number value
        getIndex (elements) {
            for (let v of Object.values(elements)) {
                let ix;
                if ( 'object' === typeof v) {

                    ix = this.getIndex(v);
                } else if ( v > 0 ) {
                    ix = v-1; //i ; the index is the text of the dropdown
                }
                if (undefined !== ix) {
                    return ix;
                }
            }
        },
        loadHier ( vals, sel=0) {
            let ix = 0;
            return getLB( vals );
            
            function getLB (vals) {
                const sub = {};
                for (let val of vals) {
                    // need to get unique key
                    let uk = val.name;
                    if ( sub[uk] ) {
                        let i=1;
                        while (sub[uk + '_' + i]) i++;
                        uk += '_' + i;
                    }
                    if (val.children) {
                        sub[ uk ] = getLB(val.children);
                    } else {
                        sub[ uk ] = (sel === ix ? 1 : -1) * (++ix);
                    }
                }
                return sub;
            }
        },
        description: {
            name: 'Test of Hierarchical list box',
            elements: [
                { type: 'static_text', name: "Doesn't provide any means to know which row is selected if it's a parent", char_width: 30},
                { type:"hier_list_box", item_id: "sub1", char_width: 30, height: 200},
                {type: "ok"}
            ]
        }
    };
    // assign bookmarks
    bkmDia.bkm = doc.bookmarkRoot.children;
    app.execDialog(bkmDia);
    
}

showBookmarks(this);

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Tue Nov 12, 2024 10:38 pm
by Mathew
By the way, this script also demonstrates another anomaly (bug?) about the "hier_list_box" implementation: It alphabetizes the rows, rather than showing them in the order indicated by the value. For example, "Syntax" should be the first row, but the other rows are shown before it.

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Wed Nov 13, 2024 3:01 pm
by Stefan - PDF-XChange
Hello Mathew,

I've asked my colleagues working on JS inside the Editor to take a look at this enquiry and we will post again when I receive their feedback.

p.s. I was asked to make a ticket so here it is:
#7186: [javascript] determine which row is selected in dialog "hier_list_box"

Kind regards,
Stefan

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Sat Nov 23, 2024 2:41 am
by Roman - Tracker Supp
Hi Mathew,
We will address both issues in the next feature release of the Editor.
- tier_list_box intermediate nodes will support selection tracking through a special (with a runtime id to facilitate uniqueness) property that holds a signed integer value - exactly as it currently works for the leaf nodes.
- tier_list_box description will support sort property that can be set to false to disable sorting.

Here is a sample code:

Code: Select all

let dlg = {
    initialize: function(dialog) {
	const id = dialog.itemIdKey;
        dialog.load({
            subl:
                {
                    "Chapter 1":
                    {
                        [id] : -1,
                        "Section 1":
                        {
                            [id] : -11,
                            "SubSection 1": -111,
                            "SubSection 2": -112,
                        },
                        "Section 2":
                        {
                            [id] : 12, // initial selection
                            "SubSection 1": -121,
                            "SubSection 2": -122,
                        }
                    },
                    "Chapter 3": -2,
                    "Chapter 4": -3
                }
        })
    },
    butn: function (dialog)
    {
        const id = dialog.itemIdKey;
        const element = dialog.store()["subl"];
        if (element["Chapter 1"]["Section 2"][id] > 0)
        {
            // the node is selected
        }
     },
    description:
    {
        name: "My Novel",
        elements:
        [
            {
                type: "view",
                align_children: "align_left",
                elements:
                [
                    {
                        type: "cluster",
                        name: "Book Headings",
                        elements:
                        [
                            {
                                type: "static_text",
                                name: "Make a selection",
                            },
                            {
                                type: "hier_list_box",
                                item_id: "subl",
                                char_width: 20,
                                height: 200, 
                                sort : false // disable sorting
                            }
                        ]
                    },
                    {
                        type: "view",
                        align_children: "align_row",
                        elements:
                        [
                            {
                                type: "button",
                                item_id: "cncl",
                                name: "Cancel"
                            },
                            {
                                item_id: "butn",
                                type: "button",
                                name: "Select"
                            }
                        ]
                    }
                ]
            }
        ]
    }
};

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Sat Nov 23, 2024 4:07 pm
by Mathew
Roman,

:D fantastic thank you!

Mathew.

[javascript] determine which row is selected in dialog "hier_list_box"

Posted: Mon Nov 25, 2024 6:26 pm
by Daniel - PDF-XChange
:)

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Mon Nov 25, 2024 7:27 pm
by Mathew
Roman - Tracker Supp wrote: Sat Nov 23, 2024 2:41 am We will address both issues in the next feature release of the Editor.
- hier_list_box intermediate nodes will support selection tracking through a special (with a runtime id to facilitate uniqueness) property that holds a signed integer value - exactly as it currently works for the leaf nodes.
- hier_list_box description will support sort property that can be set to false to disable sorting.
@Roman,
I had a couple of thoughts on this over the weekend:
  1. A 'multi_select' option would be super useful for the list_box and hier_list_box that would make all selected items positive.
  2. Based on the api examples, I'd always assumed that the list boxes would be sorted by the absolute value of the value parameter, so it really confused me that it was sorted on the key:

    Code: Select all

    dialog.load({
        subl:
            {
                "Chapter 1":
                {
                    "Section 1":
                    {
                        "SubSection 1": -1,
                        "SubSection 2": -2,
                    },
                    "Section 2":
                    {
                        "SubSection 1": -3,
                        "SubSection 2": -4,
                    }
                },
                "Chapter 3": -5,
                "Chapter 4": -6
            }
        })

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Tue Nov 26, 2024 1:17 am
by Ivan - Tracker Software
Added property multi_select.

Re: [javascript] determine which row is selected in dialog "hier_list_box"

Posted: Sat Mar 08, 2025 8:22 pm
by Mathew
Ivan - Tracker Software wrote: Tue Nov 26, 2024 1:17 am Added property multi_select.
The multi-select allows multiple selection in both hierarchical and normal list box. But in a normal list box, the result does not include the multiple items, and it makes all the indexes the same. To reproduce:

Code: Select all

// list box test
// expected output: all selected items are positive, and the index number stays the same as it was when loaded
{
    const listBoxDialog = {
        initialize (dialog) {
            dialog.load( { 'test': { 'item 1':-1, 'item 2':-2, 'item 3':-3, 'item 4':-4, 'item 5':-5},
                });
        },
        commit (dialog) {
            const data = dialog.store();
            console.println(JSON.stringify(data.test));
        },
        description: {
            name: "Multi-select test",
            elements: [
                { type: 'static_text', name: "Select multiple items and press OK:", width: 340 },
                { type: 'list_box', item_id: "test", width: 335, height: 150, sort: false, multi_select: true },
                { type: "ok_cancel" }
            ]
        }
    };
    app.execDialog(listBoxDialog);
}
If selecting item 2,3,4 only the first index is positive, and the number is repeated:

Code: Select all

{"item 1":-2,"item 2":2,"item 3":-2,"item 4":-2,"item 5":-2}

Re: [javascript] determine which row is selected in dialog "hier_list_box"  SOLVED

Posted: Mon Mar 10, 2025 5:14 pm
by Ivan - Tracker Software
Sorry for the issue. It is fixed in the upcoming build.