JScript Help - Selecting Configurable Data and Building Text String

I'm attempting to build a jscript that gives the user the choice to include any and all available parameters and put them in an order of the user's choice via the script config. The script would then build a string output that mirrors the user's choices and order. For example, say the user has the following four choices:

Bird
Cat
Dog
Fish

In the config, the user needs an option to select each; I've got that part. For example, the user identifies Bird, Cat and Dog as "true" respectively in the config.

Where I need help is in two places:

  1. Identifying the order. I'm thinking via through a number of variable assignments (ie var1 = something from drop down list, var2 = something else, etc.) in the config. Of course, the script would need each successive variable assignment to NOT include the previous var(s) selected, like a dependent dropdown list to avoid duplication. Does this sound logical? How would I do this?

  2. Building the string. I'm thinking it would have to be done via some loop process. Is that right? How would I do this?

Any suggestions or pointers for this very novice coder would be very much appreciated!

Cheers!

Chuck

It is somewhat unclear from your description what you are trying to achieve. A working example script which demonstrates the issue would likely encourage some helpful responses. :slight_smile:

Refining title bar updates based on user-selected parameters. I want to give the user control up front as to what is displayed, and in what order. Here's my code is it currently works:

function OnInit(initData)
{
	initData.name = "Custom Title";
	initData.version = "1.1";
	initData.copyright = "(c) 2019 Leo Davidson";
	initData.url = "https://resource.dopus.com/t/set-listertitle-to-include-file-display-view-mode/31991";
	initData.desc = "";
	initData.default_enable = true;
	initData.min_version = "12.0";
	
	//Get User and Machine names
	var objWSH = new ActiveXObject("WScript.Shell");
	var objEnv = objWSH.Environment("Process");
	DOpus.vars.set("ListerTitleUser",objEnv("USERNAME"));
	DOpus.vars.set("ListerTitleDomain",objEnv("USERDOMAIN"));
	var objcfg = initData.config;
	objcfg.debug = false; 
	//***NOTE:  Windows and/or DOpus limits Title Bar length to 256 characters
	//***Get Configuration Parameters; Not sure this is built appropriately
	//initData.config.program = true;
	//initData.config_desc("program") = 'Display "Directory Opus" in title bar'
	//initData.config.dopus_version = true;
	//initData.config_desc("dopus_version") = 'Identify Dirctory Opus version number in title bar'
	//initData.config.layout = true;
	//initData.config_desc("layout") = 'Identify lister layout in title bar'
	//initData.config.style = true;
	//initData.config_desc("style") = 'Identify layout style in title bar'
	//initData.config.active = true;
	//initData.config_desc("active") = 'Identify active display in title bar'
	//initData.config.view_mode = true;
	//initData.config_desc("view_mode") = 'Identify active display view mode in title bar'
	//initData.config.folder = true;
	//initData.config_desc("folder") = 'Identify active folder in title bar'
	//initData.config.filter = true;
	//initData.config_desc("filter") = 'Display "FILTERS:" in title bar'
	//initData.config.quick_filter = true;
	//initData.config_desc("quick_filter") = 'Identify QUICKFILTER state in title bar'
	//initData.config.global_filter = true;
	//initData.config_desc("global_filter") = 'Identify Global Filter state in title bar'
	//User-defined display method
	//Preferably a dropdown list per Title Bar position,
	//with subsequent dependent dropdowns that eliminate
	//prior selection(s) from available parameters
}

function OnOpenLister(OpenListerData)
{
	var tab = OpenListerData.lister.activetab;
	var cmd = DOpus.Create.Command;
	var version = DOpus.version.product;
	cmd.SetSourceTab(tab);

	//Determine layout type and identify active display on Lister open
	var tabs = tab.right;
	var dual = tab.source;
	var activeDisplay = ""

	if (dual == "1" && tabs == true)//check for dual vertical, active right display
	{
		activeDisplay = "Right"
	} else if (dual == "1" && tabs == false)//check for dual vertical, active left display
	{
		activeDisplay = "Left"	
	} else if (dual == "2" && tabs == true)//check for dual horizontal, active bottom display
	{
		activeDisplay = "Bottom"
	} else if (dual == "2" && tabs == false)//check for dual horizontal, active top display
	{
		activeDisplay = "Top"
	} else//if not dual vertical or horizontal, must be a single display
	{
		activeDisplay = "Display"
	}

	//Determine view mode status on Lister open
	var viewMode = tab.format.view;
	viewMode = viewMode.substring(0,1).toUpperCase() + viewMode.substring(1);

	//Determine global filter status on Lister open
	var filterSet = DOpus.filters.enable;
	var globalFilterFlag = ""; 
	
	if (filterSet== true)
	{
		globalFilterFlag = "ON"
	} else
	{
		globalFilterFlag = "OFF"
	}		

	//Determine quickfilter status on Lister open
	var quickFilterSet = tab.quickfilter.filter;
	var quickFilterFlag = ""
	
	if (quickFilterSet === '')
	{
		quickFilterFlag = "OFF"
	} else 
	{
		quickFilterFlag = "[ " + quickFilterSet + " ]"
	}
	
	//Build and display Title Bar syntax on Lister open
	//***Need routine to build based on user-defined parameters
	//***and parameter display order
	var title = "notoggle:Directory Opus " + version + " Pro (64-bit)      |      LAYOUT:  %L      |      STYLE:  %S      |      ACTIVE:  " + activeDisplay + "      |      VIEW:  " + viewMode + "      |      FOLDER:  %N      |      FILTERS:  Q - " + quickFilterFlag + "      G - " + globalFilterFlag;

	DOpus.Output(title);

	cmd.RunCommand('Set LISTERTITLE="' + title + '"');
}

function UpdateTitleFilter(ScriptCommandData)
{
	//update title after quickfilter applied
	cmdname = UpdateTitleFilter;
	UpdateTitle(lister);
}

function UpdateTitle(lister)
//update title bar based on user changes to lister, layout, view, etc.
{
	var tab = lister.activetab;
	var cmd = DOpus.Create.Command;
	var version = DOpus.version.product;
	cmd.SetSourceTab(tab);
	
	//Determine layout type change and identify active display
	var tabs = tab.right;
	var dual = lister.dual;
	var activeDisplay = ""
	
	if (dual == "1" && tabs == true)//check for dual vertical, active right display
	{
		activeDisplay = "Right"
	} else if (dual == "1" && tabs == false)//check for dual vertical, active left display
	{
		activeDisplay = "Left"	
	} else if (dual == "2" && tabs == true)//check for dual horizontal, active bottom display
	{
		activeDisplay = "Bottom"
	} else if (dual == "2" && tabs == false)//check for dual horizontal, active top display
	{
		activeDisplay = "Top"
	} else//if not dual vertical or horizontal, must be a single display
	{
		activeDisplay = "Display"
	}

	//Determine view mode status change
	var viewMode = tab.format.view;
	viewMode = viewMode.substring(0,1).toUpperCase() + viewMode.substring(1);

	if (cmd.IsSet("VIEW=LargeIcons"))
	{
		viewMode = "Large Icons"
	} else if (cmd.IsSet("VIEW=SmallIcons"))
	{
		viewMode = "Small Icons"
	} else
	{
		viewMode = viewMode
	}
	
	if (cmd.IsSet("FLATVIEW=on,Grouped"))
	{
		viewMode += " (Flat-Grouped)"
	} else if (cmd.IsSet("FLATVIEW=on,Mixed"))
	{
		viewMode += " (Flat-Mixed)"
	} else if (cmd.IsSet("FLATVIEW=on,MixedNoFolders"))
	{
		viewMode += " (Flat-Mixed, No Folders)"
	} else if (cmd.IsSet("VIEW=Tiles"))
	{
		viewMode += "s"
	} else if ((cmd.IsSet("VIEW=Details")) && (cmd.IsSet("COLUMNSTOGGLE=thumbnail")))
	{
		viewMode += " + Thumbnails"
	} else
	{
		viewMode = viewMode
	}
	
	//Check for quickfilter status change
	var quickFilterSet = tab.quickfilter.filter;
	var quickFilterFlag = ""
	
	if (quickFilterSet === '')
	{
		quickFilterFlag = "OFF"
	} else 
	{
		quickFilterFlag = "[ " + quickFilterSet + " ]"
	}
	
	//Check for global filter status change
	var filterSet = DOpus.filters.enable;
	var globalFilterFlag 
	
	if (filterSet == true)
	{
		globalFilterFlag = "ON"
	} else
	{
		globalFilterFlag = "OFF"
	}		
	
	//Update Title Bar syntax on layout, view, filter, etc. change
	//***Need routine to build based on user-defined parameters
	//***and parameter display order
	var title = "notoggle:Directory Opus " + version + " Pro (64-bit)      |      LAYOUT:  %L      |      STYLE:  %S      |      ACTIVE:  " + activeDisplay + "      |      VIEW:  " + viewMode + "      |      FOLDER:  %N      |      FILTERS:  Q - " + quickFilterFlag + "      G - " + globalFilterFlag;
	
	DOpus.Output(title);

	cmd.RunCommand('Set LISTERTITLE="' + title + '"');
}

function OnActivateTab(activateTabData)
{
	UpdateTitle(activateTabData.newtab.lister);
}

function OnSourceDestChange(sourceDestChangeData)
{
	UpdateTitle(sourceDestChangeData.tab.lister);
}

function OnAfterFolderChange(afterFolderChangeData)
{
	UpdateTitle(afterFolderChangeData.tab.lister);
}

function OnDisplayModeChange(displayModeChangeData)
{
	UpdateTitle(displayModeChangeData.tab.lister);
}

function OnFlatViewChange(flatViewChangeData)
{
	UpdateTitle(flatViewChangeData.tab.lister);
}

Issues:

  1. Config variables: I thought I had the config variables for the available parameters figured out, but not yet.
  2. Select config order: This is where I would think to use dependent dropdown lists (not sure if that's the right term)
  3. Build title bar: I would think this would be some sort of loop that would include a user-defined separator (another config parameter) between each selected entry.

I hope this clarifies and drives more discussion/guidance.

I don't think it's possible to have the ScriptConfig dialog dynamically change its content.

You could have a ScriptConfig textbox which accepts placeholders (each in a new line) which users can reorder as they wish. Ofcourse, that wouldn't handle duplicates nor would ensure against typos/malformed input.
alt1

Another alternative would be with dropdowns (something like this):
alt2
This protects against malformed input but still doesn't against duplicates.

Expand code example
function commonParams(default_index)
{
	return DOpus.NewVector(default_index, "DISABLED", "program", "dopus_version", "layout", "style", "active", "view_mode", "folder", "filter", "quick_filter", "global_filter")
}

initData.Config["Param 01"] = commonParams(1)
initData.Config["Param 02"] = commonParams(2)
initData.Config["Param 03"] = commonParams(3)
initData.Config["Param 04"] = commonParams(4)
initData.Config["Param 05"] = commonParams(5)
initData.Config["Param 06"] = commonParams(6)
initData.Config["Param 07"] = commonParams(7)
initData.Config["Param 08"] = commonParams(8)
initData.Config["Param 09"] = commonParams(9)
initData.Config["Param 10"] = commonParams(10)

As for building the final string, that can be easily accomplished with a loop since the config params are represented as vector type arrays.

For the first example appropriate loop would look like this:

Expand code example
var finalString = "";
for (var eParam = new Enumerator(Script.config["Params"]); !eParam.atEnd(); eParam.moveNext())
{
	var strParam = eParam.item();
	if (strParam != "DISABLED")
	{
		finalString += strParam + " | ";
	}
}

finalString = finalString.substring(0, finalString.length - 3); // Strip final " | "
DOpus.Output('finalString: "' + finalString + '"');

And for the second example loop(s) would be more involved, so I won't go into it right now.

@bytespiller Thanks for the explanation and examples! One clarification: I assume the initData.Config["Param 01"] goes into the OnInit(initData) function, correct?

I will work through this when I get the chance later this weekend.

Cheers!

Chuck

Correct!

What about a description for each initData.Config? I tried various versions of initData.config_desc without success. I would like to include a description with each.

Thanks!

After several hours toiling at this, I have reached the conclusion I have no business coding. NONE! It seems so straightforward; I can see the outcome. But the devil is in the details and I'm just not getting it.

For some reason, I can't seem to connect the defined commonParams to their respective sections in the code (ie "DO_Version = the current version as identified by DOpus.version.product) in order to build the actual DOpus.Output. I'm going down rabbit holes, crashing and burning.

My Crappy Code
function OnInit(initData)
{
	initData.name = "Custom Title";
	initData.version = "1.2";
	initData.copyright = "(c) 2019 Leo Davidson";
	initData.url = "https://resource.dopus.com/t/set-listertitle-to-include-file-display-view-mode/31991";
	initData.desc = "This script enables users to customize the Title Bar to reflect user-selected DOpus data.";
	initData.default_enable = true;
	initData.min_version = "12.0";
	
	//Get User and Machine names
	var objWSH = new ActiveXObject("WScript.Shell");
	var objEnv = objWSH.Environment("Process");
	DOpus.vars.set("ListerTitleUser",objEnv("USERNAME"));
	DOpus.vars.set("ListerTitleDomain",objEnv("USERDOMAIN"));
	var objcfg = initData.config;
	objcfg.Debug = true;
	
	//***Get Configuration Parameters
	
	//https://resource.dopus.com/t/helper-confighelper-easier-config-item-handling/19129  Helper: ConfigHelper (easier config item handling) by tbone
	function ConfigHelper(data){ //v1.2
		var t=this; t.d=data; t.c=data.config; t.cd=DOpus.Create.Map();
		t.add=function(name, val, des){ t.l={n:name,ln:name.
			toLowerCase()}; return t.val(val).des(des);}
		t.des=function(des){ if (!des) return t; if (t.cd.empty)
			t.d.config_desc=t.cd; t.cd(t.l.n)=des; return t;}
		t.val=function(val){ var l=t.l; if (l.v!==l.x&&typeof l.v=="object")
			l.v.push_back(val);else l.v=t.c[l.n]=val;return t;}
		t.trn=function(){return t.des(t("script.config."+t.l.ln));}
	}
	var cfg = new ConfigHelper(initData);
	cfg.add("DO_Program", DOpus.Create.Vector(), "Capture 'Directory Opus' name for Title Bar.  NOTE:  add 'DO_Program' to any selected position below as desired.").
		val(0).
		val("Do not display").
		val("Directory Opus").
		val("DOpus");
	cfg.add("DO_Version", true, "Check for current DOpus version.  NOTE:  add 'DO_Version' to any selected position below as desired."); 
	cfg.add("DO_Layout", true, "Retrieve current lister layout name.  NOTE:  add 'DO_Layout' to any selected position below as desired.");	
	cfg.add("DO_Style", true, "Retrieve current lister style name.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	cfg.add("DO_Active", true, "Identify current active display.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	cfg.add("DO_View", true, "Retrieve current lister view mode.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	cfg.add("DO_Folder", DOpus.Create.Vector(), "Retrieve current active folder name.  NOTE:  add 'DO_Version' to any selected position below as desired.").
		val(0).
		val("Do not display").
		val("Short path").
		val("Long path");
	cfg.add("DO_QuickFilter", true, "Check if a QuickFilter is on in the active lister tab and retrieve name.  NOTE:  add 'DO_Version' to any selected position below as desired.");
	cfg.add("DO_GlobalFilter", true, "Check if a Global Filter is active.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	cfg.add("DO_Machine", true, "Retrieve machine name.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	cfg.add("DO_User", true, "Retrieve current user name.  NOTE:  add 'DO_Version' to any selected position below as desired.");	
	
	//NOTE:  Windows and/or DOpus limits Title Bar to 256 characters
	initData.Config["Position 01"] = commonParams(1)
	initData.Config["Position 02"] = commonParams(2)
	initData.Config["Position 03"] = commonParams(3)
	initData.Config["Position 04"] = commonParams(4)
	initData.Config["Position 05"] = commonParams(5)
	initData.Config["Position 06"] = commonParams(6)
	initData.Config["Position 07"] = commonParams(7)
	initData.Config["Position 08"] = commonParams(8)
	initData.Config["Position 09"] = commonParams(9)
	initData.Config["Position 10"] = commonParams(10)
}

//Global Variables
var cmd = DOpus.create.command;
var version = DOpus.version.product;
var tab = "";
var tabs = "";
var dual = "";
var viewMode = "";
var activeDisplay = "";
var filterSet = DOpus.filters.enable;
var globalFilterFlag = "";
var quickFilterSet = "";
var quickFilterFlag = "";
var title = "";
var DO_Version = DOpus.version.product;
var DO_Layout = DOpus.lister.layout;
var DO_Style = DOpus.lister.style;
var DO_Active = activeDisplay;
var DO_View = tab.format.view;
var DO_Folder = "";

function commonParams(default_index)
{
	return DOpus.NewVector(default_index, "DISABLED", "DO_Program", "DO_Version", "DO_Layout", "DO_Style", "DO_Active", "DO_View", "DO_Folder", "DO_Filter", "DO_QuickFilter", "DO_GlobalFilter")
}

function OnOpenLister(OpenListerData)
{
	tab = OpenListerData.lister.activetab;
	cmd.SetSourceTab(tab);
	tabs = tab.right; 
	
	//Determine layout type and identify active display on Lister open
	dual = tab.source;
	
	if (dual == "1" && tabs == true)//check for dual vertical, active right display
	{
		activeDisplay = "Right"
	} else if (dual == "1" && tabs == false)//check for dual vertical, active left display
	{
		activeDisplay = "Left"	
	} else if (dual == "2" && tabs == true)//check for dual horizontal, active bottom display
	{
		activeDisplay = "Bottom"
	} else if (dual == "2" && tabs == false)//check for dual horizontal, active top display
	{
		activeDisplay = "Top"
	} else//if not dual vertical or horizontal, must be a single display
	{
		activeDisplay = "Display"
	}
	DO_Active = activeDisplay;
	
	//Determine view mode status on Lister open
	viewMode = tab.format.view;
	viewMode = viewMode.substring(0,1).toUpperCase() + viewMode.substring(1);

	//Determine global filter status on Lister open
	 
	if (filterSet== true)
	{
		globalFilterFlag = "ON"
	} else
	{
		globalFilterFlag = "OFF"
	}		

	//Determine quickfilter status on Lister open
	quickFilterSet = tab.quickfilter.filter;
	 
	if (quickFilterSet === '')
	{
		quickFilterFlag = "OFF"
	} else 
	{
		quickFilterFlag = "[ " + quickFilterSet + " ]"
	}
	
	//Build and display Title Bar syntax on Lister open
	//Program = DO_Program.val(data);
	DO_Version = version;
	
	
	var finalString = "";
	for (var eParam = new Enumerator(Script.config["Params"]); !eParam.atEnd(); eParam.moveNext())
	{
		var strParam = eParam.item();
		if (strParam != "DISABLED")
		{
			finalString += strParam + " | ";
		}
	}

	finalString = finalString.substring(0, finalString.length - 3); // Strip final " | "
	DOpus.Output('finalString: "' + finalString + '"');
	
	//title = "notoggle:Directory Opus " + version + " Pro (64-bit)      |      LAYOUT:  %L      |      STYLE:  %S      |      ACTIVE:  " + activeDisplay + "      |      VIEW:  " + viewMode + "      |      FOLDER:  %N      |      FILTERS:  Q - " + quickFilterFlag + "      G - " + globalFilterFlag;
	
	//title = "notoggle:" + Program + " " + DO_Active + " Pro (64-bit)      |      LAYOUT:  %L      |      STYLE:  %S      |      ACTIVE:  " + activeDisplay + "      |      VIEW:  " + viewMode + "      |      FOLDER:  %N      |      FILTERS:  Q - " + quickFilterFlag + "      G - " + globalFilterFlag;

	//DOpus.Output(title);

	//cmd.RunCommand('Set LISTERTITLE="' + title + '"');
}

function UpdateTitleFilter(ScriptCommandData)
{
	//update title after quickfilter applied
	cmdname = UpdateTitleFilter;
	UpdateTitle(lister);
}

function UpdateTitle(lister)
//update title bar based on user changes to lister, layout, view, etc.
{
	tab = lister.activetab;
	cmd.SetSourceTab(tab);
	tabs = tab.right;
	
	//Determine layout type change and identify active display
	dual = lister.dual;
	
	if (dual == "1" && tabs == true)//check for dual vertical, active right display
	{
		activeDisplay = "Right"
	} else if (dual == "1" && tabs == false)//check for dual vertical, active left display
	{
		activeDisplay = "Left"	
	} else if (dual == "2" && tabs == true)//check for dual horizontal, active bottom display
	{
		activeDisplay = "Bottom"
	} else if (dual == "2" && tabs == false)//check for dual horizontal, active top display
	{
		activeDisplay = "Top"
	} else//if not dual vertical or horizontal, must be a single display
	{
		activeDisplay = "Display"
	}

	//Determine view mode status change
	viewMode = tab.format.view;
	viewMode = viewMode.substring(0,1).toUpperCase() + viewMode.substring(1);

	if (cmd.IsSet("VIEW=LargeIcons"))
	{
		viewMode = "Large Icons"
	} else if (cmd.IsSet("VIEW=SmallIcons"))
	{
		viewMode = "Small Icons"
	} else
	{
		viewMode = viewMode
	}
	
	if (cmd.IsSet("FLATVIEW=on,Grouped"))
	{
		viewMode += " (Flat-Grouped)"
	} else if (cmd.IsSet("FLATVIEW=on,Mixed"))
	{
		viewMode += " (Flat-Mixed)"
	} else if (cmd.IsSet("FLATVIEW=on,MixedNoFolders"))
	{
		viewMode += " (Flat-Mixed, No Folders)"
	} else if (cmd.IsSet("VIEW=Tiles"))
	{
		viewMode += "s"
	} else if ((cmd.IsSet("VIEW=Details")) && (cmd.IsSet("COLUMNSTOGGLE=thumbnail")))
	{
		viewMode += " + Thumbnails"
	} else
	{
		viewMode = viewMode
	}
	
	//Check for quickfilter status change
	quickFilterSet = tab.quickfilter.filter;
		
	if (quickFilterSet === '')
	{
		quickFilterFlag = "OFF"
	} else 
	{
		quickFilterFlag = "[ " + quickFilterSet + " ]"
	}
	
	//Check for global filter status change
		
	if (filterSet == true)
	{
		globalFilterFlag = "ON"
	} else
	{
		globalFilterFlag = "OFF"
	}		
	
	//Update Title Bar syntax on layout, view, filter, etc. change
	//***Need routine to build based on user-defined parameters
	//***and parameter display order
	title = "notoggle:Directory Opus " + version + " Pro (64-bit)      |      LAYOUT:  %L      |      STYLE:  %S      |      ACTIVE:  " + activeDisplay + "      |      VIEW:  " + viewMode + "      |      FOLDER:  %N      |      FILTERS:  Q - " + quickFilterFlag + "      G - " + globalFilterFlag;
	
	DOpus.Output(title);

	cmd.RunCommand('Set LISTERTITLE="' + title + '"');
}

function OnActivateTab(activateTabData)
{
	UpdateTitle(activateTabData.newtab.lister);
}

function OnSourceDestChange(sourceDestChangeData)
{
	UpdateTitle(sourceDestChangeData.tab.lister);
}

function OnAfterFolderChange(afterFolderChangeData)
{
	UpdateTitle(afterFolderChangeData.tab.lister);
}

function OnDisplayModeChange(displayModeChangeData)
{
	UpdateTitle(displayModeChangeData.tab.lister);
}

function OnFlatViewChange(flatViewChangeData)
{
	UpdateTitle(flatViewChangeData.tab.lister);
}

I did NOT say it was pretty and readily admit this may be a futile exercise, but am still open to expert assistance!

initData.config_desc = DOpus.Create.Map();
initData.config_desc("Param 01") = "Param 01 description text";
initData.config_desc("Param 02") = "Param 02 description text";

Note that it is not possible for the description text to reflect the selected item from the dropdown. You can only have static descriptions for Param 01, Param 02 etc.

Don't worry, that's normal! :smiley:

Summary

https://www.youtube.com/watch?v=1uaoX3ueIzE&t=59

@bytespiller Thanks for this! Although it gets me nowhere with the script, it certainly offers sound advice for coping and staying fit... :wink:

Did you notice the voice over actually sounds like @Leo?! :grin: