extjs 4 MVC - form is undefined - forms

I'm using EXT.JS 4 with MVC.
I have a view and a controller declared as below:
view/company/MarketData.js
Ext.define('Market.view.company.MarketData', {
extend: 'Ext.form.Panel',
requires: ['Market.store.HistoricalMarketData'],
store:'HistoricalMarketData',
xtype: 'companyMarketData',
initComponent: function() {
this.callParent();
},
items: [{
xtype:'fieldset',
columnWidth: 0.5,
border:true,
padding:5,
//disabled:true,
collapsible: false,
defaultType: 'textfield',
defaults: {anchor: '100%'},
layout: 'anchor',
items :[{
fieldLabel: 'Time',
//xtype: 'displayfield',
name: 'time',
readOnly:true
}, {
fieldLabel: 'Open',
//xtype: 'displayfield',
name: 'open'
}, {
fieldLabel: 'High',
//xtype: 'displayfield',
name: 'high'
}, {
fieldLabel: 'Low',
//xtype: 'displayfield',
name: 'low'
}, {
fieldLabel: 'Close',
//xtype: 'displayfield',
name: 'close'
}, {
fieldLabel: 'Volume',
//xtype: 'displayfield',
name: 'volume'
}]
}]
});
view/controller/ChartController.js
Ext.define('Market.controller.ChartController', {
extend:'Ext.app.Controller',
stores:['HistoricalMarketData'],
models: ['MarketData'],
views: ['company.MarketData'],
init: function() {
this.control({
'#companyChartItemId series[type=column]': {
itemmouseup:this.onItemMouseUp
},
'#companyChartItemId': {
mouseenter:this.onMouseEnter
}
});
},
onItemMouseUp: function (item) {
//do something
},
onMouseEnter: function (e) {
var view = this.getCompanyMarketDataView();
var form = view.superclass.getForm();
var store = this.getHistoricalMarketDataStore();
var data = store.getAt(0);
form.loadRecord(data);
}
});
the problem is that onmouseenter event the form is undefined:
onMouseEnter: function (e) {
var view = this.getCompanyMarketDataView();
var form = view.superclass.getForm();
Any thoughts how can I recover the form from the view?

You can use Ext.ComponentQuery.query(), which returns an array of matching components.
For example
Ext.ComponentQuery.query('companyMarketData')[0].doSomething();
It is good practice to use itemIds for your components.
Also, did you try passing the default params to the onMouseEnter function?
You seem to be calling view.superclass.getForm(), but you are not passing the view param, which should be first in order. Instead, you are passing e.

Related

ExtJs getRecord() function of form does not work

I would like to get my values from my form through the getRecord() function.
This is the result im currently getting from form.getRecord():
The data object is empty.
This is my controller:
onAddNewsClick: function(button, e, eOpts) {
var win = this.getNewsEdit();
if(!win){
win = Ext.create('widget.newsedit');
}
this.getNewsPanel().loadRecord(Ext.create('model.news'));
console.log(this.getNewsPanel());
this.adding = true;
win.show();
},
OnSaveNewsClick: function(button, e, eOpts) {
var form = this.getNewsPanel();
console.log(form);
var selectedRecord = form.getRecord();
console.log(selectedRecord);
if (this.adding) {
this.adding = undefined;
}
}
The correspoding Model:
Ext.define('mobile_admin.model.News', {
extend: 'Ext.data.Model',
alias: 'model.news',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name: 'title'
},
{
name: 'newscontent'
},
{
name: 'newsdate'
},
{
name: 'status'
}
]});
With form.getValues() I get all the values of the form.
It feels like that the model is not connecting to the form. In the form I put the necessary name connection: (http://docs.sencha.com/extjs/5.1.0/Ext.form.Basic.html#method-loadRecord)
My Form items:
items: [
{
xtype: 'textfield',
fieldLabel: 'Titel',
name: 'title'
},
{
xtype: 'datefield',
fieldLabel: 'Datum',
name: 'newsdate'
},
{
xtype: 'htmleditor',
height: 150,
width: 600,
fieldLabel: 'Inhalt',
name: 'newscontent',
},
{
xtype: 'textfield',
fieldLabel: 'Status',
name: 'status'
},
]
Anyone has an idea?
I use ExtJs (5.1.3).
//EDIT:
I found out that I can set the record like this:
var b = form.getRecord()
b.set(form.getValues()
Shouln't this ExtJs do automatically?
What loadRecord really do is just setting values. Form don't use this record any more. Here is form docs:
loadRecord: function(record) {
this._record = record;
return this.setValues(record.getData());
},
You asked if setting values to record can be done automatically. Yes, it is possible, but binding is required.
I prepared a sample code:
Ext.define('mobile_admin.model.News', {
extend: 'Ext.data.Model',
alias: 'model.news',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name: 'title', defaultValue : 'test'
},
{
name: 'newscontent'
},
{
name: 'newsdate'
},
{
name: 'status'
}
]
});
Ext.define('mobile_admin.form.ViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.formpanel',
links : {
theModel : {
type : 'mobile_admin.model.News',
create : true
}
}
});
Ext.define('mobile_admin.form.formpanel', {
extend: 'Ext.form.Panel',
alias: 'widget.newsedit',
viewModel : 'formpanel',
items : [
{
xtype: 'textfield',
fieldLabel: 'Titel',
name: 'title',
bind : {
value : '{theModel.title}'
}
},
{
xtype: 'datefield',
fieldLabel: 'Datum',
name: 'newsdate',
bind : {
value : '{theModel.newsdate}'
}
},
{
xtype: 'htmleditor',
height: 150,
width: 600,
fieldLabel: 'Inhalt',
name: 'newscontent',
bind : {
value : '{theModel.newscontent}'
}
},
{
xtype: 'textfield',
fieldLabel: 'Status',
name: 'status',
bind : {
value : '{theModel.status}'
}
}],
buttons : [{
text : 'Save',
handler : function(button) {
var vM = button.up('form').getViewModel();
vM.notify();
console.log(vM.get('theModel').getData());
}
}]
});
Ext.application({
name : 'Fiddle',
launch : function() {
debugger;
var form = Ext.widget('newsedit');
var window = Ext.widget('window', {
items : form
});
window.show();
}
});

Ext Js 4 MVC with Spring and Hibernate "Remote Exception" thrown on application startup

I have created an application designed in Spring MVC3, Hibernate and Ext Js. It's a books library. I use Eclipse IDE.
In the WebContent folder i created the extjs application named app , there I uploaded extjs files too.
My application contains 4 packages: controller, model, store and view.
Controller Books.js:
Ext.define('ExtJS.controller.Books', {
extend: 'Ext.app.Controller',
stores: ['Books'],
models: ['Book'],
views: ['book.Edit', 'book.List'],
refs: [{
ref: 'booksPanel',
selector: 'panel'
},{
ref: 'booklist',
selector: 'booklist'
}
],
init: function() {
this.control({
'booklist dataview': {
itemdblclick: this.editUser
},
'booklist button[action=add]': {
click: this.editUser
},
'booklist button[action=delete]': {
click: this.deleteUser
},
'bookedit button[action=save]': {
click: this.updateUser
}
});
},
editUser: function(grid, record) {
var edit = Ext.create('ExtJS.view.book.Edit').show();
if(record){
edit.down('form').loadRecord(record);
}
},
updateUser: function(button) {
var win = button.up('window'),
form = win.down('form'),
record = form.getRecord(),
values = form.getValues();
if (values.id > 0){
record.set(values);
} else{
record = Ext.create('ExtJS.model.Book');
record.set(values);
record.setId(0);
this.getBooksStore().add(record);
}
win.close();
this.getBooksStore().sync();
},
deleteUser: function(button) {
var grid = this.getBooklist(),
record = grid.getSelectionModel().getSelection(),
store = this.getBooksStore();
store.remove(record);
this.getBooksStore().sync();
}
});
Model Book.js:
Ext.define('ExtJS.model.Book', {
extend: 'Ext.data.Model',
fields: ['id', 'title', 'author', 'publisher', 'isbn', 'pages', 'category', 'qty']
});
Store Books.js:
Ext.define('ExtJS.store.Books', {
extend: 'Ext.data.Store',
model: 'ExtJS.model.Book',
autoLoad: true,
pageSize: 35,
autoLoad: {start: 0, limit: 35},
proxy: {
type: 'ajax',
api: {
read : 'books/view.action',
create : 'books/create.action',
update: 'books/update.action',
destroy: 'books/delete.action'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json',
writeAllFields: true,
encode: false,
root: 'data'
},
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show({
title: 'REMOTE EXCEPTION',
msg: operation.getError(),
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
}
});
View contains the Viewport.js:
Ext.define('ExtJS.view.Viewport', {
extend: 'Ext.container.Viewport'
});
and a folder named book where I have:
List.js:
Ext.define('ExtJS.view.book.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.booklist',
//requires: ['Ext.toolbar.Paging'],
iconCls: 'icon-grid',
title : 'Books',
store: 'Books',
columns: [{
header: "Title",
width: 50,
flex:1,
dataIndex: 'title'
},{
header: "Author",
width: 50,
flex:1,
dataIndex: 'author'
},{
header: "Publisher",
width: 50,
flex:1,
dataIndex: 'publisher'
},{
header: "Isbn",
width: 50,
flex:1,
dataIndex: 'isbn'
},{
header: "Pages",
width: 50,
flex:1,
dataIndex: 'pages'
},{
header: "Category",
width: 50,
flex:1,
dataIndex: 'category'
},{
header: "Qty",
width: 50,
flex:1,
dataIndex: 'qty'
}],
initComponent: function() {
this.dockedItems = [{
xtype: 'toolbar',
items: [{
iconCls: 'icon-save',
itemId: 'add',
text: 'Add',
action: 'add'
},{
iconCls: 'icon-delete',
text: 'Delete',
action: 'delete'
}]
},
{
xtype: 'pagingtoolbar',
dock:'top',
store: 'Books',
displayInfo: true,
displayMsg: 'Displaying books {0} - {1} of {2}',
emptyMsg: "No books to display"
}];
this.callParent(arguments);
}
});
and
Edit.js:
Ext.define('ExtJS.view.book.Edit', {
extend: 'Ext.window.Window',
alias : 'widget.bookedit',
requires: ['Ext.form.Panel','Ext.form.field.Text'],
title : 'Edit Book',
layout: 'fit',
autoShow: true,
width: 280,
iconCls: 'icon-user',
initComponent: function() {
this.items = [
{
xtype: 'form',
padding: '5 5 0 5',
border: false,
style: 'background-color: #fff;',
fieldDefaults: {
anchor: '100%',
labelAlign: 'left',
allowBlank: false,
combineErrors: true,
msgTarget: 'side'
},
items: [
{
xtype: 'textfield',
name : 'id',
fieldLabel: 'id',
hidden:true
},
{
xtype: 'textfield',
name : 'title',
fieldLabel: 'Title'
},
{
xtype: 'textfield',
name : 'author',
fieldLabel: 'Author'
},
{
xtype: 'textfield',
name : 'publisher',
fieldLabel: 'Publisher'
},
{
xtype: 'textfield',
name : 'isbn',
fieldLabel: 'Isbn'
},
{
xtype: 'textfield',
name : 'pages',
fieldLabel: 'Pages'
},
{
xtype: 'textfield',
name : 'category',
fieldLabel: 'Category'
},
{
xtype: 'textfield',
name : 'qty',
fieldLabel: 'Qty'
}
]
}
];
this.dockedItems = [{
xtype: 'toolbar',
dock: 'bottom',
id:'buttons',
ui: 'footer',
items: ['->', {
iconCls: 'icon-save',
itemId: 'save',
text: 'Save',
action: 'save'
},{
iconCls: 'icon-reset',
text: 'Cancel',
scope: this,
handler: this.close
}]
}];
this.callParent(arguments);
}
});
My app.js:
Ext.application({
name: 'ExtJS',
controllers: [
'Books'
],
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'booklist'
}
]
});
}
});
The error "Remote exception" from store/Books.js is thrown. I don't know what can be the problem.
EDIT:
The problem is: "Error retrieving books from database". It comes from Java Controller:
#Controller
public class BookController {
private BookService bookService;
#RequestMapping(value="/books/view.action")
public #ResponseBody Map<String,? extends Object> view(#RequestParam int start, #RequestParam int limit) throws Exception {
try{
List<Book> books = bookService.getBookList(start,limit);
int total = bookService.getTotalBooks();
return ExtJSReturn.mapOK(books, total);
} catch (Exception e) {
return ExtJSReturn.mapError("Error retrieving books from database.");
}
}
See also BookService.java method:
#Transactional(readOnly=true)
public List<Book> getBookList(int start, int limit){
return bookDAO.getBooks(start, limit);
}
public int getTotalBooks(){
return bookDAO.getTotalBooks();
}
See BookDAO.java methods:
#SuppressWarnings("unchecked")
public List<Book> getBooks(int start, int limit) {
DetachedCriteria criteria = DetachedCriteria.forClass(Book.class);
return hibernateTemplate.findByCriteria(criteria, start, limit);
}
public int getTotalBooks(){
return DataAccessUtils.intResult(hibernateTemplate.find("SELECT COUNT(*) FROM books"));
}
Any idea?
Here is the problem:
org.springframework.orm.hibernate3.HibernateQueryException: books is not mapped [SELECT COUNT(*) FROM books]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: books is not mapped [SELECT COUNT(*) FROM books]
Fixed here: https://stackoverflow.com/a/14447201/1564840

Can't login to a web application through sencha app on clicking 'Sign in' button

This is my view
Ext.define("TimeSheet.view.Tracktime", {
extend: "Ext.form.Panel",
requires: ["Ext.form.FieldSet", "Ext.field.Text", "Ext.Button","Ext.Label", "Ext.field.Email", "Ext.field.Password","Ext.MessageBox", "Ext.Img"],
alias: "widget.tracktimeview",
config:{
id: 'entrypage',
fullscreen: true,
url: 'timesheet.ajatus.in/check.php',
//standardSubmit: false,
method: 'GET',
layout: {
centered: true,
},
defaults: {
styleHtmlContent: true,
//cls: 'backfield'
},
cls: 'panelBackground',
items: [{
xtype: 'fieldset',
id: 'loginfield',
autoComplete: true,
scrollable: false,
cls: 'formfield',
items: [{
xtype: 'image',
src: 'tracktime.png',
height: '60px',
cls: 'track'
},
{
xtype: 'textfield',
name : 'name',
label: 'tracktime/'
},
{
xtype: 'textfield',
name : 'uname',
allowBlank:false,
placeHolder: "User name"
},
{
xtype: 'passwordfield',
name : 'password',
allowBlank:false,
placeHolder: 'Password'
}
]
},{
xtype: 'button',
id: 'loginbtn',
cls: 'enter',
text: 'Sign in',
ui: 'confirm',
height: "50px",
}],
control: ({
'#loginbtn': {
tap: function() {
}
}
}),
},});
THIS IS CONTROLLER
Ext.define("TimeSheet.controller.Track", {
extend: "Ext.app.Controller",
config: {
refs: {
trackTimeView: "tracktimeview",
selector: '#tracktimeview',
addentryView: "addentryview",
selector: '#addentryview',
entryPage: '#entrypage',
loginBtn: '#loginbtn'
},
control:{
loginBtn: {
tap: "onLoginBtn"
},
onloginbtn: {
tap: function(btn) {
var form = Ext.getCmp('entry');
//var values = entry.getValues();
entry.submit({
method:'POST',
url: 'xxxxxxxx/check.php',
params: values,
success: function(response){
var text = response.responseText;
Ext.Msg.alert('Success', text);
},
failure : function(response) {
Ext.Msg.alert('Error','Error while submitting the form');
console.log(response.responseText);
}
});
}
},
}
},
onLoginBtn: function() {
console.log("onLoginBtn");
var values = TimeSheet.views.tracktimeview.entrypage.getValues();
TryLogin(values['uname'], values['password']);
},
launch: function () {
this.callParent(arguments);
console.log("launch");
},
init: function () {
this.callParent(arguments);
console.log("init");
}});

Chained Selectfields -- Sencha Touch 2.0

I am using the Sencha Touch 2.0 KitchenSink example to try to learn some of the basics. I am getting stuck on chained selectfields though.
I am going off the tutorial here but with the different setup I am being thrown off. The code below runs perfectly in the Forms.js file in kitchensink, but I am missing on the actual chainedselect part of it.
EDIT: What I am asking is how to make chained selectfields. I have the datastores and the selectfields in the example code, but not a working chained selectfield from first to second.
Ext.regModel('First', {
idProperty: 'FirstID',
fields: [{
name: 'FirstID',
type: 'int'
}, {
name: 'FirstName',
type: 'string'
}]
});
Ext.regModel('Second', {
idProperty: 'SecondID',
fields: [{
name: 'SecondID',
type: 'int'
},{
name: 'FirstID',
type: 'int'
}, {
name: 'SecondName',
type: 'string'
}]
});
var firstStore = new Ext.data.Store({
model: 'First',
data: [{
FirstID: 1,
FirstName: 'Kenworth'
}, {
FirstID: 2,
FirstName: 'Peterbilt'
}],
autoLoad: true
});
var secondStore = new Ext.data.Store({
model: 'First',
data: [{
SecondID: 1,
FirstID: 1,
SecondName: 'T800'
}, {
SecondID: 2,
FirstID: 1,
SecondName: 'T700'
}, {
SecondID: 3,
FirstID: 1,
SecondName: 'T660'
}, {
SecondID: 4,
FirstID: 1,
SecondName: 'T470'
}],
autoLoad: true
});
Ext.define('Kitchensink.view.Forms', {
extend: 'Ext.tab.Panel',
requires: [
'Ext.form.Panel',
'Ext.form.FieldSet',
'Ext.field.Number',
'Ext.field.Spinner',
'Ext.field.DatePicker',
'Ext.field.Select',
'Ext.field.Hidden'
],
config: {
activeItem: 0,
tabBar: {
// docked: 'bottom',
ui: 'dark',
layout: {
pack: 'center'
}
},
items: [
{
title: 'Basic',
xtype: 'formpanel',
id: 'basicform',
iconCls: 'refresh',
items: [
{
xtype: 'fieldset',
title: 'Enter Data',
instructions: 'Please enter the information above.',
defaults: {
labelWidth: '35%'
},
items: [
{
xtype: 'selectfield',
name: 'firstfield',
label: 'First',
store: firstStore,
displayField: 'FirstName',
valueField: 'FirstID'
}, {
xtype: 'selectfield',
name: 'secondfield',
label: 'Second',
store: secondStore,
displayField: 'SecondName',
valueField: 'SecondID'
}
]
}
]
}
]
},
onFirstChange: function(selectField, value){
var secondSelectField = this.items.get(1);
secondSelectField.store.clearFilter(); // remove the previous filter
// Apply the selected Country's ID as the new Filter
secondSelectField.store.filter('FirstID', value);
// Select the first City in the List if there is one, otherwise set the value to an empty string
var firstValue = secondSelectField.store.getAt(0);
if(firstValue){
secondSelectField.setValue(firstValue.data.SecondID);
} else {
secondSelectField.setValue('');
}
}
});

Extjs 4, forms with checkboxes and loadRecord

In my Extjs4 application I have a grid and a form.
The user model:
Ext.define('TestApplication.model.User', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int', useNull: true },
{ name: 'email', type: 'string'},
{ name: 'name', type: 'string'},
{ name: 'surname', type: 'string'}
],
hasMany: { model: 'Agency', name: 'agencies' },
});
And the Agency:
Ext.define('Magellano.model.Agency', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int', useNull: true},
{name: 'name', type: 'string'}
]
});
Then in my form I'm creating the checkboxes:
[...]
initComponent: function() {
var store = Ext.getStore('Agencies');
var checkbox_values = {xtype: 'checkboxfield', name: 'agencies[]'};
var checkboxes = []
store.each(function(record){
var checkbox = {xtype: 'checkboxfield', name: 'agency_ids',
boxLabel: record.get('name'), inputValue: record.get('id')};
checkbox.checked = true;
checkboxes.push(checkbox)
});
this.items = [{
title: 'User',
xtype: 'fieldset',
flex: 1,
margin: '0 5 0 0',
items: [{
{ xtype: 'textfield', name: 'email', fieldLabel: 'Email' },
{ xtype: 'textfield', name: 'name', fieldLabel: 'Nome' },
}, {
title: 'Agencies',
xtype: 'fieldset',
flex: 1,
items: checkboxes
}];
[...]
Everything works well for sending form I am receiving all the data and can save it into database.
When user clicks on the grid the record is loaded in the form with the standard:
form.loadRecord(record);
The problem is that the checkboxes are not checked. Are there any naming conventions for checkbox elements so Extjs can detect what to set? How can I setup the relations so the form will understand what to check? Or should I do everything by hand?
In your form, you can do something like this :
{
xtype: 'checkboxfield',
name: 'test',
boxLabel: 'Test',
inputValue: 'true',
uncheckedValue: 'false'
}
I believe you have to use someCheckbox.setValue(true) to check a checkbox dynamically, or to uncheck someCheckbox.setValue(false)