Related
I'm trying to create a simple GUI with the library w2ui.
But I'm having an issue while adding a toolbar to my main layout.
The toolbar is added before the layout is build.
I'm not very familiar with javascript callbacks as I am still learning.
Here is my javascript code :
function buildMainLayout(toolbar) {
$(function () {
var pstyle = 'background-color: #F5F6F7; border: 1px solid #dfdfdf; padding: 5px;';
$('#layout').w2layout({
name: 'layout',
panels: [
{ type: 'top', size: 50, resizable: true, style: pstyle, content: 'top', id: 'toolbar' },
{ type: 'left', size: 200, resizable: true, style: pstyle, content: 'left' },
{ type: 'main', style: pstyle, content: 'main' },
{ type: 'preview', size: '50%', resizable: true, style: pstyle, content: 'preview' },
{ type: 'right', size: 200, resizable: true, style: pstyle, content: 'right' },
{ type: 'bottom', size: 50, resizable: true, style: pstyle, content: 'bottom' }
]
});
}, toolbar);
$('#layout').height($( window ).height());
}
function buildMainToolbar(callback) {
$().w2toolbar({
name: 'toolbar',
items: [
{ type: 'check', id: 'item1', caption: 'Check', img: 'icon-page', checked: true },
{ type: 'break', id: 'break0' },
{ type: 'menu', id: 'item2', caption: 'Drop Down', img: 'icon-folder', items: [
{ text: 'Item 1', icon: 'icon-page' },
{ text: 'Item 2', icon: 'icon-page' },
{ text: 'Item 3', value: 'Item Three', icon: 'icon-page' }
]},
{ type: 'break', id: 'break1' },
{ type: 'radio', id: 'item3', group: '1', caption: 'Radio 1', icon: 'fa-star', checked: true },
{ type: 'radio', id: 'item4', group: '1', caption: 'Radio 2', icon: 'fa-star-empty' },
{ type: 'spacer' },
{ type: 'button', id: 'item5', caption: 'Item 5', icon: 'fa-home' }
]
}, callback);
}
function addToolbar() {
w2ui['layout'].content('top', w2ui['toolbar']);
}
Here is how I call it :
buildMainLayout(buildMainToolbar(addToolbar));
I also made a jsfiddle for my problem :
https://jsfiddle.net/e1x1cg8j/5/
Any help would be appreciated,
Thanks in advance.
I've search around but couldn't find any example using the callback as in your code.
I think that maybe you should use onRender option instead.
Something like this:
function buildMainLayout() {
$(function () {
var pstyle = 'background-color: #F5F6F7; border: 1px solid #dfdfdf; padding: 5px;';
$('#layout').w2layout({
name: 'layout',
panels: [
{ type: 'top', size: 50, resizable: true, style: pstyle, content: 'top', id: 'toolbar' },
{ type: 'left', size: 200, resizable: true, style: pstyle, content: 'left' },
{ type: 'main', style: pstyle, content: 'main' },
{ type: 'preview', size: '50%', resizable: true, style: pstyle, content: 'preview' },
{ type: 'right', size: 200, resizable: true, style: pstyle, content: 'right' },
{ type: 'bottom', size: 50, resizable: true, style: pstyle, content: 'bottom' }
],
onRender: buildMainToolbar
});
});
$('#layout').height($( window ).height());
}
function buildMainToolbar() {
$().w2toolbar({
name: 'toolbar',
items: [
{ type: 'check', id: 'item1', caption: 'Check', img: 'icon-page', checked: true },
{ type: 'break', id: 'break0' },
{ type: 'menu', id: 'item2', caption: 'Drop Down', img: 'icon-folder', items: [
{ text: 'Item 1', icon: 'icon-page' },
{ text: 'Item 2', icon: 'icon-page' },
{ text: 'Item 3', value: 'Item Three', icon: 'icon-page' }
]},
{ type: 'break', id: 'break1' },
{ type: 'radio', id: 'item3', group: '1', caption: 'Radio 1', icon: 'fa-star', checked: true },
{ type: 'radio', id: 'item4', group: '1', caption: 'Radio 2', icon: 'fa-star-empty' },
{ type: 'spacer' },
{ type: 'button', id: 'item5', caption: 'Item 5', icon: 'fa-home' }
],
onRender: addToolbar
});
}
function addToolbar() {
w2ui['layout'].content('top', w2ui['toolbar']);
}
buildMainLayout();
I'm not sure if this is the right event though.
Look into this list of events available for the layout.
-------- EDIT ---------
Also check into this
I have two radio button options, that one of it has next to it a textfield. The radiofield with the textarea next to it are showing. However the first radiofield (small) isn't showing. Any help on why?
size= Ext.create('Ext.form.Panel', {
xtype: 'fieldset',
flex: 1,
defaultType: 'radio',
width:'100%',
border:false,
items: {
checked: true,
boxLabel: 'Small',
name: 's',
inputValue: 'small',
},
layout: 'hbox',
items: [
{
boxLabel: 'Large',
name: 's',
inputValue: 'l',
},
{
xtype: 'splitter'
},
{
xtype: 'textfield',
name: 'specify'
}
]
});
Put a container around the hbox. You are now override the first items array with the second items array. You can only have one items array per container/wrapper.
size= Ext.create('Ext.form.Panel', {
xtype: 'fieldset',
flex: 1,
defaultType: 'radio',
width:'100%',
border:false,
items: {
checked: true,
boxLabel: 'Small',
name: 's',
inputValue: 'small'
}, {
xtype: 'container',
layout: 'hbox',
items: [
{
boxLabel: 'Large',
name: 's',
inputValue: 'l',
},
{
xtype: 'splitter'
},
{
xtype: 'textfield',
name: 'specify'
}]
}
});
I tried to add validation to my form using formBind: true
The validation isn't occuring though (the save button is not greyed out). The validation that the text field is not blank is occuring, but binding it to the Save button seems to do nothing.
If you double click a record it will show the form in question. This can be seen here:
http://jsfiddle.net/byronaltice/7yz9oxf6/32/
Code below in case anyone can't access jsfiddle:
Ext.application({
name: 'MyApp',
launch: function () {
//Popup form for items in grid panel
Ext.define("SessionForm", {
extend: 'Ext.window.Window',
alias: 'widget.sessionForm',
padding: 5,
width: 600,
title: 'Edit Sessions',
model: 'true',
items: [{
xtype: 'form',
bodyPadding: 10,
title: '',
items: [{
xtype: 'textfield',
name: 'title',
fieldLabel: 'Title',
labelWidth: 90,
defaults: {
labelWidth: 90,
margin: '0 0 10 0',
anchor: '90%'
},
allowBlank: false
}, {
xtype: 'checkboxfield',
name: 'approved',
fieldLabel: 'Approved'
}]
}, {
xtype: 'container',
padding: '10 10 10 10',
layout: {
type: 'hbox',
align: 'middle',
pack: 'center'
},
items: [{
xtype: 'button',
text: 'Save',
formBind: 'true',
margin: '5 5 5 5',
handler: function (button) {
var form = button.up().up().down('form');
form.updateRecord();
button.up('window').destroy();
}
}, {
xtype: 'button',
text: 'Cancel',
margin: '5 5 5 5',
handler: function (button) {
button.up('window').destroy();
}
}]
}]
});
//The grid panel area
Ext.define("SessionGridPanel", {
extend: 'Ext.grid.Panel',
alias: 'widget.sessionGridPanel',
listeners: {
itemdblclick: function (gridpanel, record, item, e) {
var formWindow = Ext.create('SessionForm');
formWindow.show();
var form = formWindow.down('form');
form.loadRecord(record);
}
},
store: {
fields: [
'id', {
name: 'title',
sortType: 'asUCText'
},
'approved', {
dateFormat: 'c',
name: 'sessionTimeDateTime',
sortType: 'asDate',
type: 'date'
}, {
convert: function (v, rec) {
var convertIt = Ext.util.Format.dateRenderer('m/d/Y g:i a'),
pretty = convertIt(rec.get("sessionTimeDateTime"));
return pretty;
},
name: 'sessionTimePretty',
type: 'string'
}],
autoLoad: true,
autoSync: true,
data: [{
id: 101,
sessionTimeDateTime: '2014-08-27T21:00:00.000+0000',
title: 'JS for D',
approved: true
}, {
id: 102,
sessionTimeDateTime: '2014-10-27T22:30:00.000+0000',
title: 'CS for S',
approved: false
}, {
id: 105,
sessionTimeDateTime: '2014-09-27T20:30:00.000+0000',
title: 'XxtJS for E',
approved: false
}, {
id: 104,
sessionTimeDateTime: '2014-09-26T22:00:00.000+0000',
title: 'ZXxtJS for E',
approved: true
}, {
id: 103,
sessionTimeDateTime: '2014-09-26T22:00:00.000+0000',
title: 'ExtJS for E',
approved: true
}],
sorters: [{
property: 'title'
}],
groupField: 'sessionTimeDateTime'
},
columns: [{
xtype: 'gridcolumn',
dataIndex: 'id',
text: 'Id'
}, {
xtype: 'gridcolumn',
dataIndex: 'title',
text: 'Title',
flex: 1,
minWidth: 100,
width: 75
}, {
xtype: 'gridcolumn',
dataIndex: 'approved',
text: 'Approved'
}, {
dataIndex: 'sessionTimePretty',
text: 'Session Start Time',
width: 180
}],
features: [{
ftype: 'grouping',
groupHeaderTpl: [
'{[values.rows[0].get(\'sessionTimePretty\')]} (Session Count: {rows.length})']
}]
});
Ext.create('Ext.container.Viewport', {
layout: {
type: 'border'
//align: 'stretch'
},
items: [{
region: 'west',
layout: {
type: 'vbox',
align: 'stretch'
},
flex: 1,
split: true,
items: [{
xtype: 'sessionGridPanel',
flex: 1
}, {
xtype: 'splitter',
width: 1
}, {
html: '<b>Speakers Panel</b>',
flex: 1,
xtype: 'panel'
}]
}, {
region: 'center',
html: '<b>Details Panel</b>',
flex: 1,
xtype: 'panel',
title: 'Details Panel',
collapsible: true,
collapsed: true,
collapseDirection: 'right'
}]
});
}
});
From Sencha API Documentation:
Any component within the FormPanel can be configured with formBind: true.
The problem is you are using the attribute formBind outside the form component
You can correct your code in this way:
Ext.define("SessionForm", {
extend: 'Ext.window.Window',
alias: 'widget.sessionForm',
// ...
items: [{
xtype: 'form',
items: [{
// your form items
}],
buttons: [{
xtype: 'button',
text: 'Save',
formBind: true,
handler: function (button) {
// also you should rewrite the following line
// to make it independant from the components structure
var form = button.up().up().down('form');
form.updateRecord();
button.up('window').destroy();
}
}, {
xtype: 'button',
text: 'Cancel',
handler: function (button) {
button.up('window').destroy();
}
}]
}]
});
Your fiddle changed: http://jsfiddle.net/7yz9oxf6/34/
I have several FormPanel. You can enter values in each of them. I need something to add all those values. Could I do it with a loop or a function? This is my code:
view1.js:
Ext.define('myApp.view.fp2', {
extend: 'Ext.form.Panel',
alias: 'widget.fp2',
config: {
id: 'fp2',
styleHtmlContent: true,
items: [
{
xtype: 'fieldset',
styleHtmlContent: true,
title: 'Prueba 3',
items: [
{
xtype: 'selectfield',
docked: 'bottom',
id: 'f3',
margin: 10,
labelWidth: '0%',
autoSelect: false,
options: [
{
text: '0',
value: 0
},
{
text: '1',
value: 1
}
]
}
]
},
{
xtype: 'fieldset',
styleHtmlContent: true,
title: 'Prueba 4',
items: [
{
xtype: 'selectfield',
docked: 'bottom',
id: 'f4',
margin: 10,
labelWidth: '0%',
autoSelect: false,
options: [
{
text: '0',
value: 0
},
{
text: '1',
value: 1
},
{
text: '2',
value: 2
}
]
}
]
},
{
xtype: 'fieldset',
styleHtmlContent: true,
title: 'Prueba 5',
items: [
{
xtype: 'selectfield',
docked: 'bottom',
id: 'f5',
margin: 10,
labelWidth: '0%',
autoSelect: false,
options: [
{
text: '0',
value: 0
},
{
text: '1',
value: 1
},
{
text: '2',
value: 2
},
{
text: '3',
value: 3
}
]
}
]
},
{
xtype: 'fieldset',
html: 'pregunta 6',
styleHtmlContent: true,
title: 'Prueba 6',
items: [
{
xtype: 'selectfield',
docked: 'bottom',
id: 'f6',
margin: 10,
labelWidth: '0%',
autoSelect: false,
options: [
{
text: '0',
value: 0
},
{
text: '1',
value: 1
}
]
}
]
}
{
xtype: 'button',
docked: 'bottom',
itemId: 'button2',
margin: 10,
ui: 'forward',
text: 'siguiente'
//go to view2.js
}
]
}
});
The view2.js is similar to the view1 but with other values.
What is the best way to sum all the values?
Thanks in advance.
To sum? I think you want to fetch them all as key-values?
For each Ext.form.FormPanel call
var valueObj = formRef.getForm().getValues();
If you now want to merge them into one object you can either do
Ext.apply(sumValueObj, valueObj ); // will override already existing props
or
Ext.applyIf(sumValueObj, valueObj ); // will not override already existing props
You can have one function which will sum all the values you need and from change event of all the selectfields you can fire that function.
In controller you can listen to change event like this:
'fp2 selectfield' : {
change : 'onDataChange'
},
and in onDataChange method you can do:
var values = Ext.getCmp("fp2").getValues();
// code to add/subtract whatever you want
PS I haven't tested this code so please ignore mistakes
I am trying to create a form through sencha touch that simply takes the text that the user enters and does a search for jobs on a website. Although everything else is working properly including the reset button but whenever I do this.getComponent('keywords') in the submitbuttonhandler it gives me an error saying Uncaught
TypeError: Object # has no method 'getComponent'.
Ext.ns('SearchJobsForm'); // register our namespace
var resetButtonHandler = function (btn, evt) {
this.getComponent('keywords').reset();
this.getComponent('dposted').reset();
this.getComponent('jtitle').reset();
this.getComponent('jcategory').reset();
this.getComponent('salaryf').reset();
this.getComponent('salaryt').reset();
this.getComponent('jscategory').reset();
this.getComponent('ptype').reset();
}
Here is the block of code that is the problem. The following block of code is not resolving 'this' the way reset button handler above is.
var submitButtonHandler = function(btn,evt) {
var temp = this.getComponent('keywords').getValue();
//query('#jcategory').getValue();
alert(temp);
//alert('In Progress');
}
The following is just creating the form.
SearchJobsForm.form = Ext.extend(Ext.Panel,{
initComponent: function(){
Ext.apply(this, {
floating: true,
width: 250,
height: 370,
scroll: 'vertical',
centered: true,
modal: true,
hideOnMaskTap: false,
items: [{
xtype: 'textfield',
itemId: 'keywords',
label: 'Keywords',
labelAlign: 'top',
labelWidth: '100%',
name: 'Keywords'
},{
xtype: 'textfield',
label: 'Job Title',
itemId: 'jtitle',
labelAlign: 'top',
labelWidth: '100%',
name: 'Job Title'
},{
xtype: 'selectfield',
label: 'Job Category',
itemId: 'jcategory',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '-- ANY --', value: 'ANY'
}, {
text: 'Technical', value: 'Technical'
}, {
text: 'Non-Technical', value: 'Non-Technical'
}, {
text: 'Tech Start-up', value: 'Tech Start-up'
}, {
text: 'Life Science', value: 'Life Science'
}, {
text: 'Digital Media', value: 'Digital Media'
}, {
text: 'Accelerator Centre', value: 'Accelerator Centre'
}
]
},{
xtype: 'selectfield',
label: 'Job Sub-Category',
itemId: 'jscategory',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '-- ANY --', value: 'ANY'
}, {
text: 'Developer', value: 'Developer'
}, {
text: 'Quality Assurance', value: 'Quality Assurance'
}, {
text: 'Project Manager', value: 'Project Manager'
}, {
text: 'Tester', value: 'Tester'
}, {
text: 'IT Help Desk', value: 'IT Help Desk'
}, {
text: 'Health Care', value: 'Health Care'
}, {
text: 'Transportation and Logistics', value: 'Transportation and Logistics'
}, {
text: 'Management', value: 'Management'
}, {
text: 'Network', value: 'Network'
}, {
text: 'Administration', value: 'Administration'
}, {
text: 'General', value: 'General'
}
]
},{
xtype: 'selectfield',
label: 'Position Type',
itemId: 'ptype',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '-- ANY --', value: 'ANY'
}, {
text: 'Part Time', value: 'Part Time'
}, {
text: 'Part Time Contract', value: 'Part Time Contract'
}, {
text: 'Full Time', value: 'Full Time'
}, {
text: 'Full Time Contract', value: 'Full Time Contract'
}
]
},{
xtype: 'selectfield',
label: 'Salary (CAD$): From',
itemId: 'salaryf',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '-- ANY --', value: 'ANY'
}, {
text: '20000', value: '20000'
}, {
text: '30000', value: '30000'
}, {
text: '40000', value: '40000'
},{
text: '50000', value: '50000'
}, {
text: '60000', value: '60000'
}, {
text: '70000', value: '70000'
}, {
text: '80000', value: '80000'
}, {
text: '90000', value: '90000'
}, {
text: '100000', value: '100000'
}, {
text: '100000+', value: '100000+'
}
]
},{
xtype: 'selectfield',
label: 'to',
itemId: 'salaryt',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '-- ANY --', value: 'ANY'
}, {
text: '20000', value: '20000'
}, {
text: '30000', value: '30000'
}, {
text: '40000', value: '40000'
},{
text: '50000', value: '50000'
}, {
text: '60000', value: '60000'
}, {
text: '70000', value: '70000'
}, {
text: '80000', value: '80000'
}, {
text: '90000', value: '90000'
}, {
text: '100000', value: '100000'
}, {
text: '100000+', value: '100000+'
}
]
},{
xtype: 'selectfield',
label: 'Posted in last (Days):',
itemId: 'dposted',
labelAlign: 'top',
labelWidth: '100%',
options: [{
text: '30', value: '30'
}, {
text: '60', value: '60'
}, {
text: '90', value: '90'
}
]
}
],
dockedItems: [{
xtype: 'toolbar',
itemId: 'toolbar',
dock: 'bottom',
height: '36',
items: [
{ xtype: 'button', text: 'Reset',itemId: 'reset',scope: this,
handler: resetButtonHandler },
{ xtype: 'spacer'},
{ xtype: 'button', text: 'Submit',
handler: submitButtonHandler
}
]
}]
});
SearchJobsForm.form.superclass.initComponent.call(this);
// alert(SearchJobsForm.form.getValues(true));
this.items.get(2).on({
change: this.onChange,
scope: this
});
},
onChange: function(selectField, value){
this.items.get(1).disable();
} //end of function onChange
});
Ext.setup({
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: false,
onReady: function(){
var form = new SearchJobsForm.form();
form.show();
}
});
this.getComponent(childId) browses through the children components of the current object. In resetButtonHandler(), this should be considered as the reset button.
SearchJobsForm is the declaration of an object not its instance. Otherwise you would have used the "new" command. SearchJobsForm.fieldName doesn't refers to a field.
So, in the submitButtonHandler() method's context, this is equivalent to : Ext.getCmp('reset');
You can use the id field (not itemId) of the component to address it in a quick and dirty way :
SearchJobsForm.form = Ext.extend(Ext.Panel,{
initComponent: function(){
Ext.apply(this, {
id: 'form', // add an id to use Ext.getCmp()
floating: true,
...
}
});
// So later you can use
Ext.getCmp('keywords')
Or go all the way up from the resetButton context to the form panel and then down to the input keywords. No need to add an attribute in this case.
var form = this.el.up('.x-panel');
var input_keyword = form.down('.x-input-text[name=Keywords]').getValue();
Regards