Morning,
I'm new to Sencha. I have the following code in my login.js, which retrieves form fields from a JSON doc on remove server. It creates an array from the data, which I need tro be able to use to populate the form:
var url = 'http://domainxxx.net/';
loginFields = new Array();
Ext.onReady(function(){var theform = Ext.Ajax.request({
url: url+'login',
type: 'get',
scope: this,
dataType: "JSON",
success: function(response){
formFields = new Array();
var numFields = Ext.JSON.decode(response.responseText).length;
for (var inf=0;inf<numFields;inf++){
afield = new Array();
afield['xtype'] = 'textfield';
afield['name'] = Ext.JSON.decode(response.responseText)[inf].Name;
afield['itemId'] = Ext.JSON.decode(response.responseText)[inf].Name;
afield['required'] = true;
afield['description'] = Ext.JSON.decode(response.responseText)[inf].Description;
afield['placeHolder'] = Ext.JSON.decode(response.responseText)[inf].Description;
afield['maxlength'] = Ext.JSON.decode(response.responseText)[inf].Length;
if(Ext.JSON.decode(response.responseText)[inf].Type == 1){afield['xtype']= 'passwordfield';}
if(Ext.JSON.decode(response.responseText)[inf].Type == 0){afield['xtype']= 'emailfield';}
loginFields.push(afield);
}
console.log(loginFields);
}
})
});
The problem is then using this variable to populate the form. I tried placing it in the form config, as shown below, but no luck. I also tried using localStorage, but that didn't work either.
Ext.define('axis3.view.Login', {
extend: 'Ext.form.Panel',
alias: "widget.loginview",
requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img'], config: {
title: 'Login',
itemId: 'loginform',
items: [
{
xtype: 'image',
src: Ext.Viewport.getOrientation() == 'portrait' ? 'images/logo.png' : 'images/logo.png',
style: Ext.Viewport.getOrientation() == 'portrait' ? 'width:271px;height:93px;margin:2em auto' : 'width:271px;height:93px;margin:2em auto'
},
{
xtype: 'label',
html: 'Login failed. Please enter the correct credentials.',
itemId: 'signInFailedLabel',
hidden: true,
hideAnimation: 'fadeOut',
showAnimation: 'fadeIn',
style: 'color:#990000;margin:5px 0px;'
},
{
xtype: 'fieldset',
title: 'Login',
items: [
FORM VARIABLES IN HERE
]
},
{
xtype: 'button',
itemId: 'logInButton',
ui: 'action',
padding: '10px',
text: 'Log In'
}
],
listeners: [{............
Any advice is most welcome
You are using an Array instead of an Object. Rather than saying var aField = new Array(), say var aField = new Object().
Note that, for short hand, you can also do this instead of using a constructor:
var myArray = [];
car myObject = {};
Related
I'm trying to use the Rally 2.1 SDK to set a custom data field (c_wsjf) in a grid. I have a custom drop down list that I want to check the value of (c_TimeCrticalitySizing).
I created c_TimeCrticalitySizing as a feature card field in my Rally workspace with different string values (such as "No decay"). Every drop down list value will set the custom field to a different integer. When I try to run the app in Rally I get this error:
"Uncaught TypeError: Cannot read property 'isModel' of undefined(…)"
I'm thinking the drop down list value may not be a string.
How would I check what the type of the drop down list value is?
How could I rewrite this code to correctly check the value of the drop down list so I can set my custom field to different integers?
Here's my code block for the complete app. I'm still trying to hook up a search bar so for now I directly call _onDataLoaded() from the launch() function.
// START OF APP CODE
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
featureStore: undefined,
featureGrid: undefined,
items: [ // pre-define the general layout of the app; the skeleton (ie. header, content, footer)
{
xtype: 'container', // this container lets us control the layout of the pulldowns; they'll be added below
itemId: 'widget-container',
layout: {
type: 'hbox', // 'horizontal' layout
align: 'stretch'
}
}
],
// Entry point of the app
launch: function() {
var me = this;
me._onDataLoaded();
},
_loadSearchBar: function() {
console.log('in loadsearchbar');
var me = this;
var searchComboBox = Ext.create('Rally.ui.combobox.SearchComboBox', {
itemId: 'search-combobox',
storeConfig: {
model: 'PortfolioItem/Feature'
},
listeners: {
ready: me._onDataLoaded,
select: me._onDataLoaded,
scope: me
}
});
// using 'me' here would add the combo box to the app, not the widget container
this.down('#widget-container').add(searchComboBox); // add the search field to the widget container <this>
},
// If adding more filters to the grid later, add them here
_getFilters: function(searchValue){
var searchFilter = Ext.create('Rally.data.wsapi.Filter', {
property: 'Search',
operation: '=',
value: searchValue
});
return searchFilter;
},
// Sets values once data from store is retrieved
_onDataLoaded: function() {
console.log('in ondataloaded');
var me = this;
// look up what the user input was from the search box
console.log("combobox: ", this.down('#search-combobox'));
//var typedSearch = this.down('#search-combobox').getRecord().get('_ref');
// search filter to apply
//var myFilters = this._getFilters(typedSearch);
// if the store exists, load new data
if (me.featureStore) {
//me.featureStore.setFilter(myFilters);
me.featureStore.load();
}
// if not, create it
else {
me.featureStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
autoLoad: true,
listeners: {
load: me._createGrid,
scope: me
},
fetch: ['FormattedID', 'Name', 'TimeCriticality',
'RROEValue', 'UserBusinessValue', 'JobSize', 'c_TimeCriticalitySizing']
});
}
},
// create a grid with a custom store
_createGrid: function(store, data){
var me = this;
var records = _.map(data, function(record) {
//Calculations, etc.
console.log(record.get('c_TimeCriticalitySizing'));
var timecritsize = record.get('c_TimeCriticalitySizing');
//console.log(typeof timecritsize);
var mystr = "No decay";
var jobsize = record.get('JobSize');
var rroe = record.get('RROEValue');
var userval = record.get('UserBusinessValue');
var timecrit = record.get('TimeCriticality');
// Check that demoniator is not 0
if ( record.get('JobSize') > 0){
if (timecritsize === mystr){
var priorityScore = (timecrit + userval + rroe) / jobsize;
return Ext.apply({
c_wsjf: Math.round(priorityScore * 10) / 10
}, record.getData());
}
}
else{
return Ext.apply({
c_wsjf: 0
}, record.getData());
}
});
// Add the grid
me.add({
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: true,
enableEditing: true,
store: Ext.create('Rally.data.custom.Store', {
data: records
}),
// Configure each column
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'WSJF Score',
dataIndex: 'c_wsjf',
width: 150
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1,
width: 100
}
]
});
}
});
// END OF APP CODE
The app works great until I add the if (timecritsize === mystr) conditional.
I also use console.log() to check that I've set all values for timecritsize to "No decay"
I have a menu system set up in a panel which needs to be dynamically created. I have created a mock static menu which the client likes but the menu categories and items will need to be loaded via JSON from a store.
Here is what I have for the first few menu items set statically:
Ext.define('SimpleSearch.view.FacetSDL' ,{
extend: 'Ext.panel.Panel',
alias : 'widget.facetsdl', //alias is referenced in MasterList.js
requires: ['SimpleSearch.store.SDLResults', 'FacetData' ],
title: 'Facet Search',
html: null,
frame: true,
layouts: 'fit',
items: [
{
id: 'group-menu',
title: 'Browse',
xtype: 'menu',
plain: true,
floating: false,
layouts: 'fit',
items: [
{
text: 'Security',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
securitymenu.setPosition(0,-groupmenu.getHeight(),false);
securitymenu.show()
}
},
menu: { // <-- submenu by nested config object
items: [
{
text: 'Classification',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
var classificationmenu = Ext.ComponentQuery.query('#classification-menu')[0];
classificationmenu.setPosition(0,-groupmenu.getHeight() - securitymenu.getHeight(),false);
classificationmenu.show()
}
I was thinking that maybe creating a class that loads all of the necessary data and then iterating through that class for the "items" field may be the way to go, but I am not sure if that will work.
You should look at using a Tree and TreeStore. Then make use of the ui:'menu' or viewConfig { ui: 'menu' } config properties to differentiate it from a regular tree. Then style it however your client wants.
This way you have all the mechanisms in place for free to handle the data dynamically and all your submenus, you'll just have to get a little creative on the CSS side of things.
I got it working like this:
var scrollMenu = Ext.create('Ext.menu.Menu');
for (var i = 0; i < store.getCount(); ++i){
var rec = store.getAt(i);
var item = new Ext.menu.Item({
text: rec.data.DISPLAY_FIELD,
value:rec.data.VALUE_FIELD,
icon: 'js/images/add.png',
handler: function(item){
myFunction(item.value); //Handle the item click
}
});
scrollMenu.add(item);
}
Then just add scrollMenu to your form or container. Hope this helps!
This menu is created dynamically with ExtJs, the data is loaded from Json.
See my demo with the code.
Demo Online:
https://fiddle.sencha.com/#view/editor&fiddle/2vcq
Json loaded:
https://api.myjson.com/bins/1d9tdd
Code ExtJs:
//Description: ExtJs - Create a dynamical menu from JSON
//Autor: Ronny Morán <ronney41#gmail.com>
Ext.application({
name : 'Fiddle',
launch : function() {
var formPanelFMBtn = Ext.create('Ext.form.Panel', {
bodyPadding: 2,
waitMsgTarget: true,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 85,
msgTarget: 'side'
},
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
]
}
]
});
var win = Ext.create('Ext.window.Window', {
title: 'EXTJS DYNAMICAL MENU FROM JSON',
modal: true,
width: 680,
closable: true,
layout: 'fit',
items: [formPanelFMBtn]
}).show();
//Consuming JSON from URL using method GET
Ext.Ajax.request({
url: 'https://api.myjson.com/bins/1d9tdd',
method: 'get',
timeout: 400000,
headers: { 'Content-Type': 'application/json' },
//params : Ext.JSON.encode(dataJsonRequest),
success: function(conn, response, options, eOpts) {
var result = Ext.JSON.decode(conn.responseText);
//passing JSON data in 'result'
viewMenuDinamical(formPanelFMBtn,result);
},
failure: function(conn, response, options, eOpts) {
//Ext.Msg.alert(titleAlerta,msgErrorGetFin);
}
});
}
});
//Generate dynamical menu with data from JSON
//Params: formPanelFMBtn - > Panel
// result - > Json data
function viewMenuDinamical(formPanelFMBtn,result){
var resultFinTarea = result;
var arrayCategoriaTareas = resultFinTarea.categoriaTareas;
var containerFinTarea = Ext.create('Ext.form.FieldSet', {
xtype: 'fieldset',
title: 'Menu:',
margins:'0 0 5 0',
flex:1,
layout: 'anchor',
//autoHeight: true,
autoScroll: true,
height: 200,
align: 'stretch',
items: [
]
});
var arrayMenu1 = [];
//LEVEL 1
for(var i = 0; i < arrayCategoriaTareas.length; i++)
{
var categoriaPadre = arrayCategoriaTareas[i];
var nombrePadre = categoriaPadre.nombreCategoria;
var hijosPadre = categoriaPadre.hijosCategoria;
var arrayMenu2 = [];
//LEVEL 2
for(var j = 0; j<hijosPadre.length; j++)
{
var categoriaHijo = hijosPadre[j];
var nombreHijo = categoriaHijo.nombreHijo;
var listaTareas = categoriaHijo.listaTareas;
var arrayMenu3 = [];
//LEVEL 3
for(var k = 0; k < listaTareas.length; k++)
{
var tarea = listaTareas[k];
var nombreTarea = tarea.nombreTarea;
var objFinLTres =
{
text: nombreTarea,
handler: function () {
alert("CLICK XD");
}
};
arrayMenu3.push(objFinLTres);
}
var menuLevel3 = Ext.create('Ext.menu.Menu', {
items: arrayMenu3
});
var objFinLDos;
if(arrayMenu3.length > 0)
{
objFinLDos = {
text: nombreHijo,
menu:menuLevel3
};
}
else
{
//without menu parameter If don't have children
objFinLDos = {
text: nombreHijo
};
}
arrayMenu2.push(objFinLDos);
}
var menuLevel2 = Ext.create('Ext.menu.Menu', {
items: arrayMenu2
});
var objFinLUno;
if(arrayMenu2.length > 0)
{
objFinLUno = {
text: nombrePadre,
menu:menuLevel2
};
}
else
{
//without menu parameter If don't have children
objFinLUno = {
text: nombrePadre
};
}
arrayMenu1.push(objFinLUno);
}
var mymenu = new Ext.menu.Menu({
items: arrayMenu1
});
containerFinTarea.add({
xtype: 'splitbutton',
text: 'Example xD',
menu: mymenu
});
formPanelFMBtn.add(containerFinTarea);
}
I am trying to add a search field to my form in sencha touch 1.1, but after going through examples provided by sencha touch, i could not find out a way to provide a dynamic store to the search field.
I have a store which will fetch data dynamically.
The store contains list of places and when the user enters the first letter of the place,he should be given a list of places starting from that alphabet
Here is the code i have used.
var searchField = new Ext.form.Search({
name : 'search',
placeHolder: 'Search',
useClearIcon: true,
data:siteStore,
autoComplete:true,
});
inputDataForm = Ext.extend(Ext.Panel, {
scroll: 'vertical',
autoDestroy: true,
layout: 'fit',
id:'inputForm',
initComponent: function() {
this.items = [{
xtype: 'form',
cls: 'formClass',
id:'inputImageForm',
bodyPadding: '0',
scroll: 'vertical',
items: [searchField],
}];
inputDataForm.superclass.initComponent.call(this);
}, // End fo initComponent
});
Can somebody please help.
Thank you
This is my code. It is working fine and I have docked the searchfield in a panel.
You can use this and I am sure it works.
, dockedItems: [{
xtype:'searchfield'
, name: "searchfield"
, placeHolder: 'Search Patient'
, id: 'searchPat'
, listeners: {
keyup: function(me,e){
var searchData = me.getValue();
Ext.Ajax.request({
url:'your data url'
, params:{
filter: searchData
}
, scope: this
, success: function(res){
var rec = Ext.decode(res.responseText);
var def = typeof (rec.success);
if(def != "undefined" ){
this.store.removeAll();
this.store.loadData(rec.patients);
}
}
, failure:function(res){
console.log(res);
}
})
}
, scope: this
}
I really hope someone can help me, It seems like this should be obvious but sencha documentation isn't very easy to read and incomplete. I am trying to build a search form but it doesnt seem to take the store or the url and I can't figure out how to add parameters like page? Can anyone help? This code just produces Failed to load resource: null.
var searchField = new Ext.form.Search({
value:'Search',
url: 'someurl',
store: this.data_store,
cls:'searchfield',
listeners: {
focus: function(){ searchField.setValue(''); },
blur: function(){ if( searchField.getValue()=='' ){ searchField.setValue('Search'); } },
success: function(e){
console.log(e);
}
}
});
this.dockedItems = [ searchField ];
Ext.form.FormPanel doesn't take a Ext.data.Store or Ext.data.Model directly but does deal with Instances of Ext.data.Model. Lets say you have the following model:
Ext.regModel('MyForm', {
fields: [{name: 'id', type: 'int'},'name','description']
proxy: {
type: 'ajax',
url: 'url_to_load_and_save_form'
}
})
Now your form definition would look something like this:
Ext.form.MyForm = Ext.extend(Ext.form.FormPanel, {
record : null,
model: 'MyForm',
items: [{
xtype: 'hidden',
name: 'id'
},{
xtype: 'textfield',
name: 'name',
allowBlank: false
},{
xtype: 'textarea',
name: 'description'
}],
submit : function(){
var record = this.getRecord() || Ext.ModelMgr.create({}, this.model);
this.updateRecord(record , true);
record.save({
scope: this,
success : function(record, opts){
this.fireEvent('saved', record);
},
callback: function(){
this.setLoading(false);
}
});
}
});
Ext.reg('MyForm',Ext.form.MyForm);
Of course you should add in some validations and a button to actually call the Ext.form.MyForm.submit method.
I know the typical reason for a DataView to be blank is because the model or JSON is wrong. From what I can tell, mine is right... so I'm not sure why my DataView is blank.
Controller
rpc.controllers.AboutController = new Ext.Panel({
id: 'rpc-controllers-AboutController',
title: 'About',
iconCls: 'info',
layout: 'card',
scroll: 'vertical',
items: [rpc.views.About.index],
dockedItems: [{ xtype: 'toolbar',
title: 'RockPointe Church | Mobile'
}],
listeners: {
activate: function () {
if (rpc.stores.AboutStore.getCount() === 0) {
rpc.stores.AboutStore.load();
}
}
}
});
View
rpc.views.About.index = new Ext.DataView({
id: 'rpc-views-about-index',
itemSelector: 'div.about-index',
tpl: '<tpl for="."><div class="about-index">{html}</div></tpl>',
store: rpc.stores.AboutStore,
fullscreen: true,
scroll: 'vertical'
});
Store
rpc.stores.AboutStore = new Ext.data.Store({
id: 'rpc-stores-aboutstore',
model: 'rpc.models.AboutModel',
autoLoad: true,
proxy: {
type: 'scripttag',
url: WebService('About', 'Index'),
method: 'GET',
reader: {
type: 'json',
root: 'results'
},
afterRequest: function (request, success) {
if (success) {
console.log("success");
} else {
console.log("failed");
}
console.log(request);
}
}
});
rpc.stores.AboutStore.proxy.addListener('exception', function (proxy, response, operation) {
console.log(response.status);
console.log(response.responseText);
});
Model
rpc.models.AboutModel = Ext.regModel('rpc.models.AboutModel', {
fields: ['html']
});
JSON
mycallback({"results":{"html":"... content removed for brevity ..."},"success":true});
Can anyone see what I might be doing wrong here?
There are no console/javascript errors. And the resources are showing that I am in fact pulling down the JSON from the WebService.
If I use console.log(rpc.stores.AboutStore.getCount()); inside my activate listener on the AboutController, the result is always 0, and I'm not entirely sure why
here's the staging app if you'd like to see the request
http://rpcm.infinitas.ws/ (note, this link will expire at some point)
Try returning your json value as an array instead of an object. I think Ext is expecting an array of records instead of just one.
For example
"{results : [{"html": "Your html"}]}"