Extjs 5 Uncaught TypeError: Cannot read property 'height' of undefined - extjs5

I changed extjs 4.2.4 to 5.0.0 and I have this error.
Uncaught TypeError: Cannot read property 'height' of undefined
SubSectionColumn.js?_dc=1451369036732:262
loadSprites: function() {
var chart = Ext.getCmp(this.identifier);
//var xAxisPositionArray = [55,95,135,175];
var xAxisPositionArray = new Array();//[55,95,175];
var yAxisStart = 0;
var xAxisHeight = chart.surface.height
var sprite;
var fromPosition;
var toPosition;
var width;
var noOfBars;
var sectionWidth = 0;
var newWidthValue = 0;
var tmp;
var chart = Ext.getCmp(this.identifier);
var storeLen =this.storeValue.getCount();
var teststore =this.storeValue;
var maxVal = 0;
for (var i =0; i<storeLen; i++){
tmp = parseFloat(teststore.data.items[i].get('data1'));
if (tmp >maxVal){
maxVal=tmp;
}
}
if(maxVal>0){
width = this.widthValue;
noOfBars = this.storeLength;//5;
sectionWidth = parseInt(parseInt(width)/parseInt(noOfBars));
for(var j=0;j<noOfBars;j++){
newWidthValue = parseInt(newWidthValue) + parseInt(sectionWidth);
xAxisPositionArray[j] = newWidthValue;
}
var gridArray = this.gridLineArrayVal.split(",");
for(var i=0;i<xAxisPositionArray.length;i++){
fromPosition = parseInt(xAxisPositionArray[i]);
toPosition = fromPosition+1;
sprite = Ext.create('Ext.draw.Sprite', {
type: 'path',
path: "M"+fromPosition+" " + yAxisStart +"L"+toPosition+" "+xAxisHeight+" Z", //if the value is "M100 40 L150 40", it's ok.
"stroke-width": (gridArray[i]=='dotted' || gridArray[i]=='line')?"0.4":"0",
"stroke-dasharray":(gridArray[i]=='dotted')?"4,4,2.5,4,4,4":"",
//"stroke-dasharray":"20,20",
stroke: "#9f9f9f",
//style:{cursor: 'pointer'},
surface: chart.surface
});
sprite.show(true);
};
maxVal=parseFloat(maxVal)*(0.10)+parseFloat(maxVal); //Math.round(maxVal)+1;
chart.axes.getAt(0).maximum = maxVal;
}
}

chart.surface is obviously undefined, as that's where you're trying to access the height property.
In ExtJS 5, there were two big changes that are likely to be relevant here. First, they tightened up on the configuration properties. Many are now prefixed, and can not be accessed by their old names. Instead, you should use (and should have used, before) the accessor methods - e.g. chart.getSurface()
Second: The charting library used in ExtJs 4 was deprecated, and has been replaced with Sencha Charts. This brought in some significant API changes.
Without more details, it's hard to say what the root cause is, but the error is definitely to do with lack of access to the surface property.

Related

Is a unicode code point can be displayed normally?

I want to know whether a unicode code point can be displayed in chrome, and check it in golang, so I can escape some parts of a string before i send it to chrome.
I have found that there is three types of unicode code point can not be displayed normally in chrome :
Space . like code point 0x20(32). ' '
Font not exist. There is a question mark in the square box. (occupy two English letters width) like code point 0x378(888) "͸"
Invaild code point value. A diamond-shaped black box with a question mark inside (occupy one English letter width) like code point 0xd800(55296) "�"
I found that I can use js and OffscreenCanvas to render all of the unicode code point and check if them looks like above three types.
Then I got a function that can tell you whether a rune/character can be displayed normally by the operating system. https://github.com/fastslothlab/fslRune
js code:
(function(){
var start = 0;
var end = 1114111;
const imageSize = 20;
var tufoCiList = [32,888,55296];
var num = end-start+1;
var startTime = performance.now()
var hasDataCiList = [];
var c = new OffscreenCanvas(imageSize,imageSize);
var ctx = c.getContext("2d");
function getImageDataByCi(ci){
var s = String.fromCodePoint(ci);
ctx.clearRect(0,0,imageSize,imageSize);
ctx.fillText(s, 5, 15);
var imgD = ctx.getImageData(0,0,imageSize,imageSize);
var hasNoneZero = false;
var buf = imgD.data;
return buf;
}
var tofuBufList = [];
for (var i in tufoCiList){
tofuBufList.push(getImageDataByCi(tufoCiList[i]));
}
function debugImage(){
c.convertToBlob({
type: "image/png",
}).then(function(blob) {
var url = URL.createObjectURL(blob);
var imgObj = document.createElement("img");
imgObj.src = url;
document.body.appendChild(imgObj);
console.log(url);
});
}
function bufEqual(buf1, buf2){
if (buf1.byteLength != buf2.byteLength) return false;
for (var i = 0 ; i != buf1.byteLength ; i++){
if (buf1[i] != buf2[i]) return false;
}
return true;
}
for (var ci =start;ci<=end;ci++){
var buf = getImageDataByCi(ci);
var hasFound = false;
for (var i in tofuBufList){
if (bufEqual(buf,tofuBufList[i])){
hasFound = true;
break;
}
}
if (hasFound){
continue;
}
hasDataCiList.push(ci);
}
console.log((performance.now()-startTime)/num);
console.log(JSON.stringify(hasDataCiList));
})();

How to get nested deep property value from JSON where key is in a variable?

I want to bind my ng-model with JSON object nested key where my key is in a variable.
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"
Here I want to get value 5 from data JSON object.
I found the solution to convert "course.sections.chapter_index" to array notation like course['sections']['chapter_index'] this. but don't know how to extract value from data now
<script type="text/javascript">
var BRACKET_REGEXP = /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/;
var APOS_REGEXP = /'/g;
var DOT_REGEXP = /\./g;
var FUNC_REGEXP = /(\([^)]*\))?$/;
var preEval = function (path) {
var m = BRACKET_REGEXP.exec(path);
if (m) {
return (m[1] ? preEval(m[1]) : m[1]) + m[2] + (m[3] ? preEval(m[3]) : m[3]);
} else {
path = path.replace(APOS_REGEXP, '\\\'');
var parts = path.split(DOT_REGEXP);
var preparsed = [parts.shift()]; // first item must be var notation, thus skip
angular.forEach(parts, function (part) {
preparsed.push(part.replace(FUNC_REGEXP, '\']$1'));
});
return preparsed.join('[\'');
}
};
var data = {"course":{"sections":{"chapter_index":5}}};
var obj = preEval('course.sections.chapter_index');
console.log(obj);
</script>
Hope this also help others. I am near to close the solution,but don't know how can I get nested value from JSON.
This may be a good solution too
getDeepnestedValue(object: any, keys: string[]) {
keys.forEach((key: string) => {
object = object[key];
});
return object;
}
var jsonObject = {"address": {"line": {"line1": "","line2": ""}}};
var modelName = "address.line.line1";
var result = getDescendantPropValue(jsonObject, modelName);
function getDescendantPropValue(obj, modelName) {
console.log("modelName " + modelName);
var arr = modelName.split(".");
var val = obj;
for (var i = 0; i < arr.length; i++) {
val = val[arr[i]];
}
console.log("Val values final : " + JSON.stringify(val));
return val;
}
You are trying to combine 'dot notation' and 'bracket notation' to access properties in an object, which is generally not a good idea.
Source: "The Secret Life of Objects"
Here is an alternative.
var stringInput = 'course.sections.chapter_index'
var splitInput = stringInput.split(".")
data[splitInput[1]]][splitInput[2]][splitInput[3]] //5
//OR: Note that if you can construct the right string, you can also do this:
eval("data[splitInput[1]]][splitInput[2]][splitInput[3]]")
Essentially, if you use eval on a string, it'll evaluate a statement.
Now you just need to create the right string! You could use the above method, or tweak your current implementation and simply go
eval("data.course.sections.chapter_index") //5
Source MDN Eval docs.
var data = {
"course": {
"sections": {
"chapter_index": 5
}
}
};
var key = "course['sections']['chapter_index']";
var keys = key.replace(/'|]/g, '').split('[');
for (var i = 0; i < keys.length; i++) {
data = data[keys[i]];
}
console.log(data);
The simplest possible solution that will do what you want:
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']";
with (data) {
var value = eval(key);
}
console.log(value);
//=> 5
Note that you should make sure key comes from a trusted source since it is eval'd.
Using with or eval is considered dangerous, and for a good reason, but this may be one of a few its legitimate use cases.
If you don't want to use eval you can do a one liner reduce:
var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"
key.split(/"|'|\]|\.|\[/).reduce((s,c)=>c===""?s:s&&s[c], data)

How to access an object in AS3

I wrote this code
var enemies:Object = new Object();
// HP MP ATK DEF MATK MDEF AGI LUCK
enemies.Goblin = [40, 20, 6, 6, 3, 3, 4, 1];
which contains those stats for the goblin and I created a function that should take the stats from enemies.Goblin and put them in some variables but it won't work.
function createEnemy(enemyName:String):void {
e_hp = enemies.enemyName[0];
e_mp = enemies.enemyName[1];
e_atk = enemies.enemyName[2];
e_def = enemies.enemyName[3];
e_matk = enemies.enemyName[4];
e_mdef = enemies.enemyName[5];
e_agi = enemies.enemyName[6];
e_luck = enemies.enemyName[7];
}
This is the output error when the createEnemy function is executed: TypeError: Error #1010: A term is undefined and has no properties.
Object "enemies" does not have "enemyName" property.
Try this:
enemies[enemyName][0]
enemies[enemyName][1]
...
The answer had been given but what are you doing is a wrong way to do. Accessing properties by index is asking for trouble in a very near future.
It is better to do with classes but since you're using objects, I will try use objects too:
var goblin_stats:Object = { hp:40, mp:20, atk:6, def:6 }; // and so on
var elf_stats:Object = { hp:35, mp:30, atk:8, def:4 }; // and so on
...
// add as much characters as needed
Now I believe you just want to create a fresh goblin based on goblin stats. Just pass the stats to the createEnemy function:
createEnemy(goblin_stats);
function createEnemy(stats:Object):void {
e_hp = stats.hp;
e_mp = stats.mp;
// and so on
}
or better:
function createEnemy(stats:Object):void {
for (var property:String in stats) e_stats[property] = stats[property];
}
Store objects (everything) in arrays for easy referencing. Here are the key code:
var aEnemies:Array = new Array();
var mcEnemy:Object = new Object();
mcEnemy.iHP = 40; // set iHP property to 40
aEnemies.push(mcEnemy); // add enemy to array of enemies
trace("enemy 0's HP: " + aEnemies[0].iHP);

GAS - Sort a flexTable by column

I understand that cellTable in GWT performs this (Sort FlexTable Inquiry) and I was wondering if anyone knew a way to emulate some of the column sorting behaviour using a flexTable in UiApp.
In my case it is only necessary for the app to sort the column once at creation, not have it sortable by the user on click. I have included my flexTable creation code below:
var flexTable = app.createFlexTable()
.setStyleAttribute('marginTop', '10px')
.setCellPadding(5)
.setCellSpacing(2);
for(var i = 0;i<(size-1);i++){
var class = "class" + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
var text10 = statusObjectsIndex[classCode].classname;
var text11 = statusObjectsIndex[classCode].homeworkstatus;
var text12 = statusObjectsIndex[classCode].classcalendarlink;
var anchor = app.createAnchor('Calendar', text12)
.setTarget('_blank');
var calPanel = app.createAbsolutePanel()
.add(anchor);
flexTable.setText(i, 0, text10);
flexTable.setText(i, 1, text11);
flexTable.setWidget(i, 2, calPanel);
if(text11 == "No homework set for this class"){
flexTable.setRowStyleAttribute(i, "backgroundColor", "#96bcfd")
flexTable.setRowStyleAttribute(i, "color", "#000000");
}else{
flexTable.setRowStyleAttribute(i, "backgroundColor", "#eca8a3");
flexTable.setRowStyleAttribute(i, "color", "#FFFFFF");
};
}
app.add(flexTable);
Due to the way in which the table is populated sorting the array the values are pulled from will not help.
This the first question I have posted here, please be gentle. If I could ask it in a better way, I have overlooked an obvious resource to get my answer or if there is more information I need to provide please let me know!
EDIT//////////////////////////////////
I was having trouble sorting using the code provided, very helpfully, by Serge and so I approached it slightly differently and created individual objects for each row of data. The advice given by both Serge and Zig helped me end up with this working solution, many thanks!
//create flexTable
var flexTable = app.createFlexTable();
flexTable.setStyleAttribute('marginTop', '10px')
flexTable.setCellPadding(5);
flexTable.setCellSpacing(2);
//create empty table array to store rowObjects
var tableArray =[];
//create rowObjects
for(var i = 0; i<(size-1); i++){
var rowObject = {};
var class = 'class' + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
rowObject.className = statusObjectsIndex[classCode].classname;
rowObject.homeworkStatus = statusObjectsIndex[classCode].homeworkstatus;
rowObject.link = app.createAbsolutePanel().add(app.createAnchor('Calendar',statusObjectsIndex[classCode].classcalendarlink));
if(statusObjectsIndex[classCode].homeworkstatus == "No homework set for this class"){
rowObject.BGColor = "#96bcfd";
rowObject.color = "#000000";
}else{
rowObject.BGColor = "#eca8a3";
rowObject.color = "#FFFFFF";
}
tableArray.push(rowObject);
}
//sort objects in array by homework status
tableArray.sort(function (a, b) {
if (a.homeworkStatus > b.homeworkStatus)
return 1;
if (a.homeworkStatus < b.homeworkStatus)
return -1;
return 0;
});
//populate flextable
for(var i = 0;i<(size-1);i++){
flexTable.setText(i,0, tableArray[i].className);
flexTable.setText(i,1, tableArray[i].homeworkStatus);
flexTable.setWidget(i,2, tableArray[i].link);
flexTable.setRowStyleAttribute(i, 'color', tableArray[i].color);
flexTable.setRowStyleAttribute(i, 'backgroundColor', tableArray[i].BGColor);
};
app.add(flexTable);
Theres nothing that prevents you from sorting the source array first. Just store each 5 columns (3 data columns plus background/foreground colors) as rows in another array and sort that other array. After sort populate the table.
I fully agre with Zig on this, here is an example of such an implementation to help you figure out how to approach it. (code not tested but should be right)
var flexTable = app.createFlexTable()
.setStyleAttribute('marginTop', '10px')
.setCellPadding(5)
.setCellSpacing(2);
var array = [];
var t0 = [];
var t1 = [];
var t2 = [];
var color = [];
var BGcolor = [];
for(var i = 0;i<(size-1);i++){
var class = "class" + (i+1);
var classCode = classObjectsIndex[loggedInUser][class];
t0.push(statusObjectsIndex[classCode].classname);
t1.push(statusObjectsIndex[classCode].homeworkstatus);
t2.push(app.createAbsolutePanel().add(app.createAnchor('Calendar',statusObjectsIndex[classCode].classcalendarlink)));
if(statusObjectsIndex[classCode].homeworkstatus == "No homework set for this class"){
color.push("#000000")
BGcolor.push("#96bcfd")
}else{
color.push("#FFFFFF")
BGcolor.push("#eca8a3")
};
array.push(t0,t1,t2,color,BGcolor);
}
// sort the array here
array.sort();// use other sort parameter if you want, search SO for examples
for(var n in array){
flexTable.setText(i, 0, array[n][0]);
flexTable.setText(i, 1, array[n][1]);
flexTable.setWidget(i, 2, array[n][2]);
flexTable.setRowStyleAttribute(i, array[n][3])
flexTable.setRowStyleAttribute(i, array[n][4]);
}
app.add(flexTable);

How to move a popup window from a client handler?

I have a code that simulates a popup window (thanks to Waqar Ahmad) that is triggered by a client handler.
I would like to get this popup appear near the button that triggered it but with the script I have I see no way to move the window.
The code is below and the app is viewable here, if ever someone has an idea about how I should re-organise or change the script so that the popup window shows up near the button that fired the process ?
var choice = ['-','Choice 1','Choice 2','Choice 3','Choice 4']; // var definition
function doGet(){
var app = UiApp.createApplication().setStyleAttribute("background", "beige");
app.add(createMaskPanel_());//this is used to make popup panel modal
var mainPanel = app.createVerticalPanel().setStyleAttributes({'padding' : '15'});
app.add(mainPanel);
// idx holds the index value of the button that is pressed
var idx = app.createTextBox().setId('idx').setName('idx').setVisible(false);
mainPanel.add(idx);
//Make a panel for popup and add your popup elements
var popup = app.createVerticalPanel().setId('popup').setVisible(false)
.setStyleAttributes(
{'position': 'fixed',
'border' : '1px solid brown',
'padding' : '15',
'background' : 'beige',
'top' : '150PX',
'left' : '300PX',
'width' : '200',
'height':'120',
'zIndex' : '2'});
popup.add(app.createLabel('Select your choice').setId('label'));
var list = app.createListBox().setId('ppValue').setName('ppValue').setWidth('200')
.addItem(choice[0], '0').addItem(choice[1], '1').addItem(choice[2], '2').addItem(choice[3], '3').addItem(choice[4], '4');
popup.add(list);
var valHandler = app.createServerHandler('showVal').addCallbackElement(mainPanel).addCallbackElement(popup);;
popup.add(app.createButton('✖ Close / confirm').addClickHandler(valHandler));
app.add(popup);
var mask = app.getElementById('mask')
var ppHandler = app.createClientHandler().forTargets([popup,mask]).setVisible(true)
var flex = app.createFlexTable()
for(nn=1;nn<11;++nn){
flex.setText(nn,0,'Item nr '+nn)
var text = app.createTextBox().setHeight('26').setWidth('150').setId('val'+nn).setName('val'+nn)
flex.setWidget(nn,1,text);
var handler = app.createClientHandler().forTargets(idx).setText(nn).forTargets(text).setText('suggestion = ?');
flex.setWidget(nn,2,app.createButton('✐').setHeight('26').setId('btn'+nn).addClickHandler(handler).addClickHandler(ppHandler))
}
mainPanel.add(flex);
return app;
}
function createMaskPanel_(){ //Called when UI loads, initially it will be invisble. it needs to be made visible
var app = UiApp.getActiveApplication();
var mask = app.createVerticalPanel().setId('mask').setSize('100%', '100%') //maskPanel to mask the ui
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.4'}).setVisible(false);
mask.add(app.createLabel('POPUP')
.setStyleAttribute('color', '#F0F0F0')
.setStyleAttribute('opacity', '0.6'));
return mask;
}
function showVal(e){
var app = UiApp.getActiveApplication();
var source = e.parameter.idx
var value = app.getElementById('val'+source)
value.setText('choice value = '+choice[e.parameter.ppValue])
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
popup.setVisible(false)
mask.setVisible(false)
return app
}
EDIT : Since the server handler seems to be the only way I gave it a try, the app is viewable here and the (final ?) code is below for info.
var choice = ['-','Choice 1','Choice 2','Choice 3','Choice 4','Choice 5','Choice 6','Last choice !'];//var definition
function doGet(){
var app = UiApp.createApplication().setStyleAttribute("background", "beige");
app.add(createMaskPanel_());//this is used to make popup panel modal
var top = '100PX'
var left = '265PX'
var mainPanel = app.createVerticalPanel().setStyleAttributes({'padding' : '15'});
app.add(mainPanel);
// item definitions
var idx = app.createTextBox().setId('idx').setName('idx').setVisible(false);
mainPanel.add(idx);
//Make a panel for popup and add your popup elements
var popup = app.createVerticalPanel().setId('popup').setVisible(false)
.setStyleAttributes(
{'position': 'fixed',
'border' : '1px solid brown',
'padding' : '10',
'background' : 'beige',
'top' : top,
'left' : left,
'width' : '200',
'height':'110',
'zIndex' : '2'});
popup.add(app.createLabel('Select your choice').setId('label'));
var list = app.createListBox().setId('ppValue').setName('ppValue').setWidth('160')
for(c in choice){list.addItem(choice[c], c)}
popup.add(list);
var valHandler = app.createServerHandler('showVal').addCallbackElement(mainPanel).addCallbackElement(popup);;
popup.add(app.createButton('✖ Close / confirm').addClickHandler(valHandler));
app.add(popup);
var idxHandler = app.createServerHandler('setidx').addCallbackElement(mainPanel)
var flex = app.createFlexTable()
for(nn=1;nn<11;++nn){
flex.setText(nn,0,'Item nr '+nn)
flex.setWidget(nn,1,app.createTextBox().setPixelSize(180,26).setId('val'+nn).setName('val'+nn));
flex.setWidget(nn,2,app.createButton('✐').setHeight('26').setId('btn'+nn).addClickHandler(idxHandler))
}
mainPanel.add(flex);
return app;
}
function setidx(e){
var app = UiApp.getActiveApplication();
var idx = app.getElementById('idx')
var idxval = Number(e.parameter.source.replace(/[a-z]/g,''))
idx.setValue(idxval);
var top = -30+38*idxval+'PX'
var left = '265PX'
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
var label = app.getElementById('label').setText('Select your choice (item '+idxval+')')
var value = app.getElementById('val'+idxval)
value.setText('suggestion = ?')
popup.setVisible(true)
mask.setVisible(true)
popup.setStyleAttributes(
{'top' : top,
'left' : left});
return app
}
function createMaskPanel_(){ //Called when UI loads, initially it will be invisble. it needs to be made visible
var app = UiApp.getActiveApplication();
var mask = app.createVerticalPanel().setId('mask').setSize('100%', '100%') //maskPanel to mask the ui
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.6'}).setVisible(false);
mask.add(app.createLabel('POPUP')
.setStyleAttribute('color', '#F0F0F0')
.setStyleAttribute('opacity', '0.6'));
return mask;
}
function showVal(e){
var app = UiApp.getActiveApplication();
var source = e.parameter.idx
var value = app.getElementById('val'+source)
value.setText('choice value = '+e.parameter.ppValue+' ('+choice[Number(e.parameter.ppValue)]+')')
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
popup.setVisible(false)
mask.setVisible(false)
return app
}
Serge I did something simular using a dialogbox to get this kind of functionality.
In the proper function that shows the dialogbox I decide the position of the dialogbox.
I used it to enlarge a image so I just put the (entire) code I used for the dialogbox.
function showimg(e){
var app = UiApp.getActiveApplication();
//
// Style
//
var _showimg =
{
"position":"fixed",
"width":"200px", // here you can change size
"top":"100px", // and horizontal position maybe you can use your
"left":"100px", // your setidx function .
"opacity":"0.95",
"border":"none",
}
var _container =
{
"width":"90%",
"border":"none",
}
var _img= {
"background-color":"none",
"width":"90%",
"border":"4px solid f2f2f2",
}
var _btn= {
"background-color":"none",
"background":"none",
"width":"80px",
"height":"24px",
"border":"None",
"font-family":"hobo std",
"font-size":"0.9em",
"color":"3f3f3f",
"opacity":"1",
}
//
// aplication
//
var f = DocsList.find("YOURSPREADSHEET");
var id = f[0].getId();
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("YOURSHEET");
var rows= sheet.getLastRow();
var cols = sheet.getLastColumn();
var dialogBox = app.createDialogBox(true, true).setId("dialogBox");
applyCSS(dialogBox, _showimg);
var cont = app.createAbsolutePanel().setId("cont").setVisible(true);
applyCSS(cont, _container);
var source = e.parameter.source;
for (var i = 1; i < rows ; i++) {
for (var j = 1; j <6 ; j++) {
if (source == "imgb"+[j]+[i]) {
if (j == 1) {
var img = app.createImage().setId('img').setUrl(sheet.getRange(i+1,[5]).getValue()).setVisible(true);
dialogBox.setText(sheet.getRange(i+1,[6]).getValue());
}
if (j == 2) {
var img = app.createImage().setId('img').setUrl(sheet.getRange(i+1,[7]).getValue()).setVisible(true);
dialogBox.setText(sheet.getRange(i+1,[8]).getValue());
}
}
app.getElementById( "imgb"+[j]+[i]).setEnabled(false);
//}
}
}
applyCSS(img,_img)
app.createImage().setId('img').setUrl("https://lh6.googleusercontent.com/-PTl6c-pfHoc/TzFvp1dteaI/AAAAAAAACTI/Mmx-7RU4i8g/s640/xxxxxxx.jpg").setVisible(true);
// applyCSS(img,_img)
var closeb = app.createButton("Close").setId("closeb").setTitle("close");
applyCSS(closeb,_btn);
var closeH = app.createServerClickHandler("closediag");
closeb.addClickHandler(closeH);
closeH.addCallbackElement(cont);
cont.add(img);
cont.add(closeb);
dialogBox.add(cont);
app.add(dialogBox);
return app;
}
The applyCss from James
function applyCSS(element, style){
for (var key in style){
element.setStyleAttribute(key, style[key]);
}
}
From what I've discovered so far using what I see in these replies, this methodology is positioning my widgets accordingly, but not the actual form itself. Unless, of course, I'm missing something, which is entirely possible. Thanks for the replies so far.