Copy link to clipboard
Copied
Good day!
I have a script that does some work based on data from csv files. When working with a script, a user can upload several files sequentially (i.e., after finishing working with one file, I need to make it so that the user can load another without closing the script window). The csv files have a different structure and a different number of fields (this is controlled by the user) - it seemed to me convenient to show them using a listbox with headers.
Before the user specifies the file, I open the form with an empty listbox object (just to reserve a place for it in the form):
After reading and processing the csv file, I create a new listbox object using the buildList() function. To do this, I delete the previously created testList object from the form, then load a new one in its place. And at this moment i have a problem with ScriptUI:
If I do not delete the object, then the listbox will display normally (but old instances will be preserved):
It is clear that i can rewrite the function so that for each csv file a new instance of the window is loaded in which a listbox with the necessary parameters will be immediately generated, but in my case this is inconvenient for the user.
I trying to understand - is this a bug of ScriptUI or am I doing something wrong?
(the example is simplified, just to demonstrate the problem)
#target photoshop
var parsedCSV = [["TestField1", "TestField2", "060", "070", "080", "090"], ["TestField3", "TestField4", "145"], ["TestField5", "TestField6", "361"]]
var w = new Window("dialog"),
oldList = w.add('listbox', [0,0,520,200]),
bn = w.add("button", undefined, "test")
bn.onClick = function () {
w.remove (oldList) // problem here, i'm trying also w.remove (w.children[0])
buildList(parsedCSV)
}
w.show ()
function buildList (list) {
var columns=0,
wordLen={}
for (var i=0; i<list.length; i++){
if (list[i].length>columns) columns = list[i].length
for (var n=0; n<list[i].length; n++){
if (wordLen[n]=undefined) {
wordLen[n] = list[i][n].length
} else {
if (list[i][n].length > wordLen[n]) wordLen[n] =list[i][n].length
}
}
}
var props = { numberOfColumns: columns, showHeaders: true, columnTitles: [], columnWidths: [] }
for (var i=0; i<columns; i++){
props.columnTitles.push(String(i+1))
props.columnWidths.push(wordLen[i]*12)
}
newList = w.add("listbox", [0, 0, 520, 200], undefined, props)
for (var i = 0; i < list.length; i++) {
var cur = list[i]
newList.add("item", cur[0])
for (var n = 1; n < cur.length; n++) {
newList.items[i].subItems[n - 1].text = cur[n];
}
}
w.layout.layout(true)
}
var parsedCSV = [["TestField1", "TestField2", "060", "070", "080", "090"], ["TestField3", "TestField4", "145"], ["TestField5", "TestField6", "361"]]
var w = new Window("dialog")
w.p1 = w.add("group");
w.p1.margins = 0;
w.p2 = w.p1.add("group");
w.p2.margins = 0;
oldList = w.p2.add('listbox', [0,0,520,200], [1,2,3]);
bn = w.add("button", undefined, "test")
bn.onClick = function () {
w.p1.remove(w.p2);
buildList(parsedCSV)
}
w.show
...
Copy link to clipboard
Copied
Change this example (where innitially there's one set replaced by other when clicking button) to your needs:
lst = (win = new Window('dialog')).add('dropdownlist', [0, 0, 100, 20], [])
lst.add('item', [1, 2, 3]), btn = win.add('button', [0, 0, 60, 21], 'Replace')
btn.onClick = function() {lst.removeAll(), lst.add('item', [4, 5])} win.show()
Copy link to clipboard
Copied
The problem is that the set of headers in the listbox can be changed ONLY when it is created (i.e. numberOfColumns, showHeaders, columnTitles is a creation properties). It’s not enough for me to simply clear list, I need to recreate the object itself with a different set of fields
Copy link to clipboard
Copied
Change appropriate lines of your script to these codes:
var w = new Window("dialog"), grp = w.add('group')
oldList = grp.add('listbox', [0,0,520,200])
grp.remove (grp.children[0]) // problem here, i'm trying also w.remove (w.children[0])
newList = grp.add("listbox", [0, 0, 520, 200], undefined, props)
Copy link to clipboard
Copied
Same result. Any other objects are deleted and created in this way normally, the problem is only in the listbox with headers.
It seems i have found a solution: if put the listbox in another object (group or panel) and delete not listbox, but his parent (with creating a new one in the function), then everything works fine:
#target photoshop
var parsedCSV = [["TestField1", "TestField2", "060", "070", "080", "090"], ["TestField3", "TestField4", "145"], ["TestField5", "TestField6", "361"]]
var w = new Window("dialog"),
bn = w.add("button", undefined, "test"),
grp = w.add('group'),
oldList = grp.add('listbox', [0,0,520,200])
bn.onClick = function () {
w.remove (w.children[1]) // remove parent
buildList(parsedCSV)
}
w.show ()
function buildList (list) {
var columns=0,
wordLen={}
for (var i=0; i<list.length; i++){
if (list[i].length>columns) columns = list[i].length
for (var n=0; n<list[i].length; n++){
if (wordLen[n]=undefined) {
wordLen[n] = list[i][n].length
} else {
if (list[i][n].length > wordLen[n]) wordLen[n] =list[i][n].length
}
}
}
var props = { numberOfColumns: columns, showHeaders: true, columnTitles: [], columnWidths: [] }
for (var i=0; i<columns; i++){
props.columnTitles.push(String(i+1))
props.columnWidths.push(wordLen[i]*12)
}
var grp = w.add('group'),
newList = grp.add("listbox", [0, 0, 520, 200], undefined, props)
for (var i = 0; i < list.length; i++) {
var cur = list[i]
newList.add("item", cur[0])
for (var n = 1; n < cur.length; n++) {
newList.items[i].subItems[n - 1].text = cur[n];
}
}
w.layout.layout(true)
}
Copy link to clipboard
Copied
Try following codes (in your first script with my previous changes).
Under your first parsedCSV array paste:
var parsedCSV2 = [["TestField2", "070", "080", "090"], ["TestField4", "TestField5", "155"], ["TestField6", "TestField7", "371"]]
while appropriate line in bn.onClick function change to:
buildList(!$.getenv('csv') ? ($.setenv('csv', 1), parsedCSV) : ($.setenv('csv', ''), parsedCSV2))
btw the groups you say you found you can put the list to I already posted as solution to a problem, didn't you notice it? 🙂
Copy link to clipboard
Copied
Checked. Got the same result.
The problem is that the number of headers can vary. Please note - first I create an empty listbox with no headers (just so that the user sees the place of the object on the form). Only after parsing csv (receiving an array in this example) I determine how many headers are needed and create a listbox with this headers for a specific file - that’s why I recreate the object, and not just changing the dataset in it.
Believe me, I carefully read your messages and try all the proposed options 🙂 You did not offer to remove the parent itself, but proposed to remove the object from his parent - unfortunately, this does not work as expected in that case (but works fine with any other scriptUI objects in 99% of cases). Try to run my first example and you will understand what the problem is. When only reading code without running it, it is not obvious.
Anyway, thanks. I always read your comments with interest.
Copy link to clipboard
Copied
I read twice what you wrote now and I'm sure I know what you asked for. So to make it clear I'm posting your first script of first set of my updates and then of those from another post. Run it and tell me if that is not what you wanted. As you see depending of number of cells in array the number of headers varies, so isn't that okey?
btw I tried the script originally in CS6, where it works well. I guess that must be same Ps on your side because later I tried it in CC2019 and CC2020 and after clicking Test button nothing happened.
Anyway if that's CS6 try my script and see it works the way I understood it should.
Ps. the environmental variables I used only because CSV data is put in variables not in outer file, the content of may be changed.
var parsedCSV = [["TestField1", "TestField2", "060", "070", "080", "090"], ["TestField3", "TestField4", "145"], ["TestField5", "TestField6", "361"]]
var parsedCSV2 = [["TestField2", "070", "080", "090"], ["TestField4", "TestField5", "155"], ["TestField6", "TestField7", "371"]]
var w = new Window("dialog"), grp = w.add('group')
oldList = grp.add('listbox', [0,0,520,200])
bn = w.add("button", undefined, "test")
bn.onClick = function () {
grp.remove (grp.children[0]) // problem here, i'm trying also w.remove (w.children[0])
buildList(!$.getenv('csv') ? ($.setenv('csv', 1), parsedCSV) : ($.setenv('csv', ''), parsedCSV2))
}
w.show()
function buildList (list) {
var columns=0,
wordLen={}
for (var i=0; i<list.length; i++){
if (list[i].length>columns) columns = list[i].length
for (var n=0; n<list[i].length; n++){
if (wordLen[n]=undefined) {
wordLen[n] = list[i][n].length
} else {
if (list[i][n].length > wordLen[n]) wordLen[n] =list[i][n].length
}
}
}
var props = { numberOfColumns: columns, showHeaders: true, columnTitles: [], columnWidths: [] }
for (var i=0; i<columns; i++){
props.columnTitles.push(String(i+1))
props.columnWidths.push(wordLen[i]*12)
}
newList = grp.add("listbox", [0, 0, 520, 200], undefined, props)
for (var i = 0; i < list.length; i++) {
var cur = list[i]
newList.add("item", cur[0])
for (var n = 1; n < cur.length; n++) {
newList.items[i].subItems[n - 1].text = cur[n];
}
}
w.layout.layout(true)
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
They encourage to use HTML and Javascript Extensions instead of ScriptUI.
Copy link to clipboard
Copied
Morons.
Copy link to clipboard
Copied
var parsedCSV = [["TestField1", "TestField2", "060", "070", "080", "090"], ["TestField3", "TestField4", "145"], ["TestField5", "TestField6", "361"]]
var w = new Window("dialog")
w.p1 = w.add("group");
w.p1.margins = 0;
w.p2 = w.p1.add("group");
w.p2.margins = 0;
oldList = w.p2.add('listbox', [0,0,520,200], [1,2,3]);
bn = w.add("button", undefined, "test")
bn.onClick = function () {
w.p1.remove(w.p2);
buildList(parsedCSV)
}
w.show ()
function buildList (list) {
var columns=0,
wordLen={}
for (var i=0; i<list.length; i++){
if (list[i].length>columns) columns = list[i].length
for (var n=0; n<list[i].length; n++){
if (wordLen[n]=undefined) {
wordLen[n] = list[i][n].length
} else {
if (list[i][n].length > wordLen[n]) wordLen[n] =list[i][n].length
}
}
}
var props = { numberOfColumns: columns, showHeaders: true, columnTitles: [], columnWidths: [] }
for (var i=0; i<columns; i++){
props.columnTitles.push(String(i+1))
props.columnWidths.push(wordLen[i]*12)
}
w.p2 = w.p1.add("group");
newList = w.p2.add("listbox", [0, 0, 520, 200], undefined, props)
for (var i = 0; i < list.length; i++) {
var cur = list[i]
newList.add("item", cur[0])
for (var n = 1; n < cur.length; n++) {
newList.items[i].subItems[n - 1].text = cur[n];
}
}
w.layout.layout(true)
}
Copy link to clipboard
Copied
Thanks. A few messages above i found some solution
Find more inspiration, events, and resources on the new Adobe Community
Explore Now