I’m writing a simple application using EXT-JS 4.0 for creating quick surveys. The questions and their answering options are contained and transferred through a JSON object which is then dynamically displayed. Each question has a text displayed using a DisplayField instance (xtype: 'displayfield') and resides, along with the answering options, in a Ext.form.Panel instance. Depending on the JSON object, answering might be through free text (using a TextAreaField), a choice 1-of-many (using radio buttons), or many-of-many (using check boxes).
After decoding the JSON object, I iterate through the questions with a regular for loop to dynamically create the necessary widgets (holding panel, question text, text area, check boxes, and radio buttons, and a submit button for testing). After the loop, I add these panels to a Container with layout: 'vbox' and finally add the container to a viewport with layout: 'fit'.
This is the format of the JSON object to display the questions:
{questions: [{
question:'Do you know it?',
comment: 'no',
multiple: [],
single: ['yes','no']
}, {
question:'In which seasons do you use it (add your comment with your selection)?',
comment: 'yes',
multiple: ['Winter','Spring','Summer','Fall'],
single: []
}
]}
And there is my code:
Ext.onReady(function () {
// Decode the received JSON object..
var jsonObj = Ext.JSON.decode(jsonObjStr);
// Array to hold the to-be-created panels for rendering in global container..
var panels = new Array();
for (i = 1; i <= jsonObj.questions.length; i++) {
// Create a Panel to contain the question..
var formPanel = Ext.create('Ext.form.Panel', {
id: 'panel' + toString(i),
frame: false,
border: true,
title: 'Question ' + i,
width: '75%',
margin: '10 0 0 0',
fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
buttonAlign: 'center',
anchor: '100%'
}
});
// Add the question text first..
var questionText = {
xtype: 'displayfield',
name: 'questionTextTf' + i,
value: '<b>' + jsonObj.questions[i - 1].question + '</b>'
};
formPanel.add(questionText);
// Add the check boxes for many-of-many answers..
var checkBoxes = new Array();
for (imultiple = 0; imultiple < jsonObj.questions[i - 1].multiple.length; imultiple++) {
var itemChk = {
name: 'cb' + i,
id: 'cb' + toString(i) + '-' + toString(imultiple),
boxLabel: jsonObj.questions[i - 1].multiple[imultiple]
};
checkBoxes.push(itemChk);
}
if (jsonObj.questions[i - 1].multiple.length > 0) {
var multipleFieldContainer = {
xtype: 'checkboxgroup',
name: 'multipleContainer' + i,
id: 'multipleContainer' + toString(i),
fieldLabel: 'Select all that match',
items: checkBoxes
};
formPanel.add(multipleFieldContainer);
}
// Add the radio buttons for one-of-many answers..
var radioBoxes = new Array();
for (isingle = 0; isingle < jsonObj.questions[i - 1].single.length; isingle++) {
var itemRdb = {
name: 'rb' + i,
id: 'rb' + toString(i) + '-' + toString(isingle),
boxLabel: jsonObj.questions[i - 1].single[isingle]
};
radioBoxes.push(itemRdb);
}
if (jsonObj.questions[i - 1].single.length > 0) {
var singleFieldContainer = {
xtype: 'radiogroup',
name: 'singleContainer' + i,
id: 'singleContainer' + toString(i),
fieldLabel: 'Select one',
items: radioBoxes
};
formPanel.add(singleFieldContainer);
}
// Add the text area field for free text comments..
if (jsonObj.questions[i - 1].comment == 'yes') {
var commentArea = {
xtype: 'textareafield',
name: 'commentTa' + i,
id: 'commentsTa' + toString(i),
fieldLabel: 'Comment'
};
formPanel.add(commentArea);
}
// Add the submit button for each question (for testing)..
var sendButton = {
xtype: 'button',
name: 'submitBtn' + i,
id: 'submitBtn' + toString(i),
text: 'Submit',
handler: function () {
Ext.Msg.alert('Info', Ext.getCmp('commentsTa' + toString(i)).getId() + ': ' + Ext.getCmp('commentsTa' + toString(i)).getValue());
}
};
formPanel.add(sendButton);
// Add panel to array of panels for later rendering..
panels.push(formPanel);
}
// Create the global container to contain all the created panels..
var mainContainer = Ext.create('Ext.container.Container', {
html: 'First Set of Preliminary Questions: <br>',
//renderTo: 'form-ct1',
style: {
borderColor: '#000000',
borderStyle: 'solid',
borderWidth: '2px'
},
layout: {
type: 'vbox',
align: 'center'
},
items: panels
});
// Create a viewport to render the global container to fill the body region of the page..
var viewport = Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: mainContainer,
autoScroll: true
});
});
Now the problems are:
-
If there are too many panels to be displayed on the page, the autoscroll of the viewport doesn’t cover all the subsequent panels. That is, I can’t see all of them!
-
If I execute the code above with the id of the widgets set according to the following pattern, for example
id: 'commentsTa'+toString(i), only the last widget of each type is displayed. This is because they all seem to take the same value since the expressiontoString(i)turns out to be interpreted as[object DOMWindow]. If I don’t use thetoString()then theidis not recognised at all and can’t use theExt.getCmp()method.
I’d really appreciate your help with these issues!
For the first problem, vertical scroll bars are not created for a container with a
vBoxlayout. The aim of such a layout is to keep all the contained elements within the containing box. Removing this layout and using the default one would solve this problem.As for the second problem:
1- To convert from int to String then:
2- To convert from String to int then: