Page 1 of 1

get parent content in popupnested()

Posted: 15 Mar 2017 03:08
by SkyFrontier
Is there a way I'm missing so popupnested() could return both data AND category (data or caption) it belongs to at the same time?

Code: Select all

category 1; data 1
 item 1
 item 2
category 2; data 2
 item 3
 item 4
category 3; data 3
 item 5
 item 6 if I pick 'item 5' I can also retrieve 'DATA 3' ?
Thanks in advance!

popupnested - get all menu names as path?

Posted: 15 Mar 2017 12:30
by rur54
I came across "popupnested" and have been trying it out but can not figure out how to get entire manu path.

For example if I click on Cb2, I would like to get entire path (all parents and child) like A1\B3\Cb2.
Any way to get that path?

Thank you all.

from help..

Code: Select all

$menu = <<<MENU

  text popupnested($menu);

Re: popupnested request

Posted: 15 Mar 2017 12:41
by highend
Merged. Closely related
update: edited title & menu text in codeview - ss

Re: get parent content in popupnested()

Posted: 15 Mar 2017 17:22
by SammaySarkar
Made a wrapper function to popupnested(). It's only a rough draft a few versions above a rough draft.


Code: Select all

FUNCTION popupnestedpath($itemlist, $x=-1, $y=-1, $start=1, $count=-1, $flags=0, $sep_itemlist="|", $sep_item=";", $on_cancel="", $sep_path="\", $data=0) {
  // A wrapper to popupnested() that returns menu path to the picked menuitem
  //  $*           all params are equivalent to popupmenu(), except $flags
  //               $flags is hardcoded to 1 in function body because we cannot work without its indexed return.
  //  $sep_path    separator in returned path. Default is "\"
  //  $data         0  default behavior - that is, return data, if not available then return caption
  //                1  return caption
  //                2  return data
  //               -1  return both

  $return  = "";                                                                         // holds returned path
  $pattern = "^(\s|\t)*";                                                                // submenu indentation pattern
  $index   = popupnested($itemlist, $x, $y, $start, $count, 1,                           // run popupnested() with provided params and get picked index
                         $sep_itemlist, $sep_item, $on_cancel);
  if ($index == $on_cancel) { return $on_cancel; }                                       // popupnested() returned $on_cancel, assume nothing picked
  $index   = $index + ($start>1 ? $start-1 : 0);                                         // adjust returned index if $start defined ($start is 1-based)
  $first   = strlen(regexmatches(gettoken($itemlist, 1, $sep_itemlist), $pattern));      // record root indentation
  $pathstr = gettoken($itemlist, $index, $sep_itemlist);                                 // get picked item from $itemlist
  $indent  = strlen(regexmatches($pathstr, $pattern));                                   // record picked item's indentation
  $pathstr = popupnestedpath_extractdatacaption($pathstr, $sep_item, $data);
  $return  = substr($pathstr, $indent);                                                  // start path construction with picked item's text
  if ($indent == $first) {                                                               // shortcut logic when picked item is at root level
    $pathstr = substr(gettoken($itemlist, $index, $sep_itemlist), $indent);              // in that case, simply (process and) return the picked item
    $return  = popupnestedpath_extractdatacaption($pathstr, $sep_item, $data);
  } else {                                                                               // else continue with part construction
    $line    = $index;                                                                   // line counter for the while() loop
    while ($line >= $start && $indent > $first) {                                        // loop thru $itemlist lines upwards from picked item till start index set by $start
      $loopline   = gettoken($itemlist, $line, $sep_itemlist);                           // record current line in loop
      $loopindent = strlen(regexmatches($loopline, $pattern));                           // record indent of current line
      if ($loopindent < $indent) {                                                       // IF (this logic) THEN current line is parent to previously recorded  path item
        $indent  = $loopindent;                                                          // set indent to current indent - this skips siblings with same indent as current
        $pathstr = substr($loopline, $indent);                                           // strip indent from current line
        $pathstr = popupnestedpath_extractdatacaption($pathstr, $sep_item, $data);
        $return  = $pathstr . $sep_path . $return;                                       // prepend parent text to return path
      $line--;                                                                           // move line index up so next loop processes the line above current in $itemlist
  return $return;

// helper function to get data and/or caption from menuitem definition
FUNCTION popupnestedpath_extractdatacaption($str, $sep, $mode) {
  if ($mode == -1) {
    return $str;
  } elseif ($mode == 0) {
    return (strpos($str, $sep) > -1) ? gettoken($str, 2, $sep) : $str;
  } else {
    return gettoken($str, $mode, $sep);


  • save function to <xyscripts>\_inc\popupnestedpath.xyi.
  • code:

    Code: Select all

    INCLUDE "_inc\popupnestedpath.xyi";
      // define a variable with the menu structure
      $itemlist = <<<#MENUSTRUCT
    category 1;data 1
      item 1
      item 2
    category 2;data 2
      item 3
      item 4
    category 3;data 3
      item 5
      item 6
      category 3.1;data 3.1
        item 7
        item 8
    item 9
    item 10#MENUSTRUCT;
      text popupnestedpath($itemlist,,, /*start*/,,, /*sep_itemlist*/ <crlf>,,, /*sep_path*/ '|');
  • returns:

    Code: Select all

    pick     |  return
    item 8      category 3;data 3|category 3.1;data 3.1|item 8
    item 4      category 2;data 2|item 4
    item 10     item 10
  • can return incorrect path if source indentation is mixed or not strictly valid. Even if the menu looks okay. For example:

    Code: Select all

    category 3;data 3
      item 5
      item 6
       category 3.1;data 3.1  < bad indent
        item 7  < bad indent
         item 8  < bad indent
    This may also happen when $start is defined such that the menu starts from a sublevel but still has higher level items (and one of those highlevel items are selected).
edit: removed an unnecessarily duplicated gettoken() call. added logic to handle cancelled return.

Re: get parent content in popupnested()

Posted: 15 Mar 2017 19:51
by rur54
Thank you! Works well so far.

Re: get parent content in popupnested()

Posted: 18 Mar 2017 05:37
by SkyFrontier
...kool, Sammay.

Pretty kool.

Now I'll have to rewrite my entire beta 3, fully functional, error-handling-only-pending super-script I've waited for, what?, 5 years now?, so I can have a better interface for copyto\moveto\bkpto ops.

Are you willing to HTML-something so bkpto ops get a better user end input? Input() multiline is ultimate lame, and it's the best I could cope with so far... :roll:

Thanks, man! Ultra again. Integration, step 1 is looking sharp & pretty.

Re: get parent content in popupnested()

Posted: 18 Mar 2017 06:47
by SammaySarkar
Thanks mate.
HTML control panel? Sure.

Re: get parent content in popupnested()

Posted: 18 Mar 2017 06:58
by SkyFrontier
You rock, Sammay!
Fully integrated.
I'll mail you the base code, then. You know the scheme... :wink:

Many thanks!

Re: get parent content in popupnested()

Posted: 22 Mar 2017 03:05
by SkyFrontier
extra-thanks: this is allowing me to work towards a multi-level rating system, which will ultimately give me freedom to develop a custom text-based XY categorization (thus portable, like smartFavs already does) method to plug it with.

Superb, Sammay!


Re: get parent content in popupnested()

Posted: 22 Mar 2017 04:23
by SammaySarkar
:D Thank you! Glad to help.