This (sub)function is part of a larger appie I'm currently working on (not sure how I'm gonna name the larger app yet , for now called it RlxBlockSync but also entertaining the idea to call RFD, redefine for dummies )
 
	 
 
	Anyways, this sub dynamically creates a dialog and takes 'commatized' strings for input. Few years ago I wrote Tokkie, this basically does the same , just a little different and with less code. I was inspired by a similar function master L created and later Grrr made something like that.
 
	 
 
	The reason I use commatized / csv strings is so I can save the output of this function as a string in the registry. Added little test function which generates 3 list boxes but you can have as many LB's as you like, the only limitations are your imagination and the width of your monitor. I hope by analyzing the test function (c:t1) you understand how you can use this function.
 
	 
 
	 
	 
; multiple input listbox function : mlist = ( ( description1 (labels1) (defaults1) ) ...)
(defun milf ( mlist / get_lb_width commatize de-commatize _ufo toggle fn fp dcl lb-width old-props new-props plist tmp out)
  ; get max strlen from list arguments for milf
  (defun get_lb_width (l) (apply 'max (mapcar 'strlen (apply 'append (mapcar 'de-commatize (mapcar 'cadr l))))))
  ; (commatize '("a" "b" "c"))  ->  "a,b,c"
  (defun commatize (l) (apply 'strcat (cdr (apply 'append (mapcar '(lambda (x) (list "," x)) l)))))
  ; (de-commatize "a,b,c")  ->   ("a" "b" "c")
  (defun de-commatize (s / p)(if (setq p (vl-string-search "," s))(cons (substr s 1 p)(de-commatize (substr s (+ p 2))))(list s)))
  ; use filter on : (_ufo "*" '("door" "table" "floor")) (_ufo "o" '("door" "table" "floor"))
  (defun _ufo ( f l ) (if (and (= (type f) 'STR) (/= f ""))
    (vl-remove-if '(lambda (s)(not (or (eq f "*") (vl-string-search (strcase f)(strcase s))))) l)))
  ; adds / removes [0] or [X] before each item in listboxes
  (defun toggle (k v / lst r s)
    (if (eq (substr (setq r (nth (atoi v) (setq lst (cdr (assoc k plist))))) 2 1) "X") (setq s "[O] ") (setq s "[X] "))
      (setq plist (subst (cons k (setq lst (subst (strcat s (substr r 5)) r lst))) (assoc k plist)  plist))
        (start_list k)(mapcar 'add_list lst)(end_list)(set_tile k v))
  ; calculated width of list boxes by finding longest string
  (setq lb-width (+ (get_lb_width mlist) 5))
  (if (not (setq fp (open (setq fn (vl-filename-mktemp ".dcl")) "w")))
    (princ "\nUnable to create temporary dcl file")
    (progn
      (write-line "milf:dialog {label=\"Multiple Input Listbox Function (RLX 5/'20)\";:row {" fp)
      (setq lb 0)
      (foreach item mlist (write-line (strcat ":column {label=\"" (car item)
         "\";:list_box{height=16;width=" (itoa lb-width)  ";key=\"lb" (itoa (setq lb (1+ lb))) "\";}}") fp))
      (write-line "}ok_cancel;}" fp)(if fp (progn (close fp)(gc)))
      (if (not (and (< 0 (setq dcl (load_dialog fn))) (new_dialog "milf" dcl)))
        (princ "\nUnable to start dialog milf")
        (progn
          (setq lb 0)
          (foreach item mlist
            (setq old-props (de-commatize (cadr item)) new-props (de-commatize (caddr item)))
            (setq l (mapcar '(lambda (x)(if (member x new-props)(strcat "[X] " x)(strcat "[O] " x))) old-props))
            (setq lb-id (strcat "lb" (itoa (setq lb (1+ lb))))  plist (cons (cons lb-id l) plist))
            (start_list lb-id) (mapcar 'add_list l) (end_list)
            (action_tile (strcat "lb" (itoa lb)) "(toggle $key $value)")
          )
          (action_tile "accept" "(done_dialog 1)")
          (action_tile "cancel" "(done_dialog 0)")
          (setq drv (start_dialog)) (unload_dialog dcl)(vl-file-delete fn)
        )
      )
    )
  )
  (if (= drv 1) (mapcar '(lambda (x)(commatize (mapcar '(lambda (y)(substr y 5)) x)))
                   (mapcar '(lambda (x)(_ufo "[X]" x))(mapcar 'cdr (reverse plist)))) nil)
)
(defun c:t1 ( / result-list animals breakfast music)
  (setq animals "Aardvark,Baboon,Camel,Dragons,Easterbunny,Firebird,Godzilla,Hobbit,Idiot,Phoenix")
  (setq breakfast "Anna Nicole,Beyoncé Knowles,Carmen Electra,Daenerys Targaryen,Ella Enchanted,Gal Gadot,Sophie Turner")
  (setq music "Andrea Bocelli,Electric Light Orchestra,Earth Wind & Fire,George Michael,Lara Fabian,Queen")
  (setq result-list
         (milf
           (list
             (list "Animals" animals "Dragons,Phoenix")
             (list "Breakfast" breakfast "Gal Gadot,Sophie Turner")
             (list "Music" music "Electric Light Orchestra,Lara Fabian")
             ;;; add as many list as you want limited only by the size of the screen
           )
         )
  )
  (princ "\n\nYou made the following selections : ")
  (mapcar '(lambda (label value) (princ (strcat "\n\n" label "\nvalue : " value)))
          '("Animals :" "Breakfast :" "Music :" ) result-list)
  (princ "\n\n")
  (princ)
)
 
	 
 
	I can show you how other app looks , but that's not finished yet (if ever) so will get back to that later
 
	 
 
	
 
	 
 
	Awell... hope I didn't forget any sub functions that are allways loaded automatically on my own pc (autoload & forget) but if so let me know (wouldn't be the first time I forgot something and probably not the last time)
 
	 
 
	happy coding