Component selector in Extjs 4 - javascript

I'm trying to select multiple objects (2 labels & 2 textfields) that are located in a panel. I gave these components a property (changeVisibility: true).
So the thing i'm trying to accomplish here is quite simple: when the user checks the checkbox, all the components with the property (changeVisibility:true) should become invisible. So in my controller i'm trying to select these components but i'm unable to accomplish this thusfar.
Help is much appreciated!
Code of my panel:
Ext.define('Edocs.view.wizard.card-2.content.mobile-password.Panel', {
extend : 'Ext.FormPanel',
alias : 'widget.mobilePassword',
layout : {
type : 'vbox',
pack: 'center'
},
bodyStyle:{"background-color":"beige"},
border:false,
defaults:{
width: '100%'
},
items: [{
xtype : 'checkboxfield',
boxLabel : 'Enable mobile (iphone) accesibility',
boxLabelAlign : 'before',
name : 'enableMobile',
inputValue : '1',
id : 'cbxMobile',
itemId : 'cbxMobile'
},{
xtype: 'label',
text: "Please enter a password to connect to the platform by mobile (iphone/ipad)",
style: 'font-weight:bold;',
changeVisibility :true
},{
xtype: 'textfield',
name: 'mobilePassword',
id: 'txtMobilePassword',
inputType: 'password' ,
changeVisibility :true
//width: '100%'
},{
xtype: 'label',
text: "Confirm password",
style: 'font-weight:bold;',
changeVisibility :true
},
{
xtype: 'textfield',
name: 'mobilePasswordConfirm',
itemId: 'txtMobilePasswordConfirm',
inputType: 'password' ,
vtype: 'password',
initialPassField: 'txtMobilePassword',
changeVisibility :true
}],
initComponent : function() {
Ext.apply(this, {})
this.callParent(arguments);
}
});
This is the function in my controller (this function is called on the change event of the checkbox):
addMobilePassword : function(checkbox) {
var items = checkbox.up().down('mobilePassword[changeVisibility=true]');
if (checkbox.checked){
for (var i in items){
items[i].setVisible(false);
}
}
}
I'm having troubles with this selector:
var items = checkbox.up().down('mobilePassword[changeVisibility=true]');
If anyone could give me some advice on how to select these components.
Thanks!

down() will find the first matched descendant of the container. So I think you should try:
checkbox.up().down('mobilePassword').query('label[changeVisibility], textfield[changeVisibility]')
or briefer
checkbox.up().query('label[changeVisibility], textfield[changeVisibility]')

Try query('[changeVisibility=true]')

Related

w2ui grid hide and show not working properly

I am working on w2ui grid and I need to hide and show it based on certain condition. Grid is not showing back even though visibility:visible property is applied after it is hidden. It is just showing a line.
Please have a look at my code below:
HTML:
<div id="LastMileGrid" class="col-lg-6 col-sm-12 col-md-6" style="width: 100%; height: 150px"></div>
Javascript:
$('#LastMileGrid').w2grid({
name: 'LastMile',
show: {
toolbar: true,
footer: true,
toolbarReload: false,
toolbarColumns: false,
lineNumbers: true,
},
columns: [
{ field: 'recid', caption: 'ID', size: '10%', sortable: true },
//{ field: 'Header', caption: 'Header', size: '20%', editable: { type: 'text' }, sortable: true },
{ field: 'Description', caption: 'Description', size: '50%', editable: { type: 'text' }, sortable: true }
],
toolbar: {
items: [
{ id: 'add', type: 'button', caption: 'Add Record', icon: 'w2ui-icon-plus' },
{ id: 'remove', type: 'button', caption: 'Remove Record', icon: 'w2ui-icon-cross' }
],
onClick: function (event) {
if (event.target == 'add') {
var Index = w2ui['LastMile'].records.length;
w2ui['LastMile'].add({ recid: w2ui['LastMile'].records.length + 1 });
}
if (event.target == 'remove') {
var grid = w2ui["LastMile"];
grid.method = 'DELETE';
grid.delete();
}
}
},
//records: [{ recid: 'AAA' }, { recid: 'BBB' }, { recid: 'CCC' }]
});
And when opening the pop up I call the function,
$('#popup').w2popup('open', {
onOpen: function () {
if ($("#ddlMode").val() == "AIR" && ($("#drpServiceScope").val() == "D2D" || $("#drpServiceScope").val() == "A2D")) {
$('#LastMileGrid').attr("style", "visibility:visible;height:160px:")
}
else {
$('#LastMileGrid').attr("style", "visibility:collapse;")
}
},
modal: true,
});
You can try to call w2ui["LastMile"].refresh() after hiding or showing.
Answering to help others as I am late :D.
After spending a lot of time to resolve the issue,I have formulize below 2 solutions for w2ui grid show hide issue or column size issue :
1.Change the size of columns to px instead of %.
ie. use
{ field: 'lname', caption: 'Last Name', size: '30px' }
instead of
{ field: 'lname', caption: 'Last Name', size: '30%' },
2. If you wish to keep column size in % due to some requirement:
Depending on where you are rendering grid,you need to handle the resizing.
Calling refresh on grid will send data request again to server.
I don't wanted grid to make call to server each time I show/hide grid, hence written the resize of my own.
To help understand the function please note that in my application,
I have followed naming convention as follows:
If I create a grid then it will be id+"_grid",
If create a form that it will be id+"_form",
same for layout id+"_layout".
So I can get the associated component to a id and establish relation between them.
Call resize() function after you call show().
If below function doesn't help, try adding some milli seconds delay between show and my function resize().
function resize(id){
var grid=id+"_grid";
var layout=id+"_layout";
var form=id+"_form";
if(w2ui[layout]){
if($(w2ui[layout].el("main")).hasClass("w2ui-grid")){ /*means in w2ui layouts main has grid hence call resize. Calling refresh on layout "main" will make grid to reload data again ,hence grid resizing is handled in next case */
w2ui[layout].resize();
}else{
w2ui[layout].refresh();/*means main has element other than grid so refresh */
}
}
if(w2ui[form])
w2ui[form].resize();
if(w2ui[grid])
w2ui[grid].resize(); //if grid is directly rendered without a layout resize helps
}

How to create a dynamic (on the fly) form in Sencha Touch

I am working in a sencha touch ap and I need to generate views with dynamic forms.
Configuration comes from the backend (JSON) and depending of this I paint a component or other.. for example:
"auxiliaryGroups": [
{
"id": "1000",
"name": "Basic Data",
"fields": [
{
"id": "1001",
"name": "Company name",
"editable": true,
"mandatory": true,
"calculation": true,
"internalType": "T",
"type": "textfield",
"options": []
}
]
}
],
Where type is related xtype in Sencha.
In the view I am creating all options of fields:
{
xtype : 'fieldset',
itemId: 'auxiliaryFieldsGroup3',
title: 'Requirements',
//cls : 'headerField',
items:[
{
xtype: 'togglefield',
name: 'f6',
label: 'Auxiliary field R1'
},
{
xtype: 'selectfield',
name: 'f10',
label: 'Auxiliary field R5',
placeHolder: 'Select one..',
options: [
{text: 'First Option', value: 'first'},
{text: 'Second Option', value: 'second'},
{text: 'Third Option', value: 'third'}
]
},
{
xtype: 'textfield'
}
]
}
And I receive the configuration from the server, I understand the view like a store of different fields, and from the controller, it should add only fields specified in the json object.
How to create this dynamically following MVC concept?
Thank you
I assume that you have all the fields in the auxiliaryGroups.fields array.
After loading the form data from AJAX you can do it like this in your success call.
succses:function(response){
var response = Ext.decode(response.responseText);
var fields = response.auxiliaryGroups.fields;
var form = Ext.create("Ext.form.Panel",{
// here your form configuration.
cls:"xyz"
});
Ext.Array.forEach(fields,function(field){
var formField = {
xtype: field.type,
label: field.name,
name: field.id
};
form.add(formField);
});
Ext.Viewport.add(form);
form.show();
}
Based on my comment on your question, my idea about dynamic form generation is using ExtJS syntax to load form definition would be something like the code below; of course it would be extended and the data can be loaded from the server.
Ext.require([
'Ext.form.*'
]);
Ext.onReady(function() {
var data = [{
fieldLabel: 'First Name',
name: 'first',
allowBlank: false
}, {
fieldLabel: 'Last Name',
name: 'last'
}, {
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype: 'email'
}, {
xtype: 'timefield',
fieldLabel: 'Time',
name: 'time',
minValue: '8:00am',
maxValue: '6:00pm'
}];
var form = Ext.create('Ext.form.Panel', {
frame: true,
title: 'Simple Form',
bodyStyle: 'padding:5px 5px 0',
width: 350,
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
defaultType: 'textfield',
defaults: {
anchor: '100%'
}
});
form.add(data);
form.render(document.body);
});
update:
When you create a view in run-time, communication between view and controller might be problematic because the controller doesn't know anything about the view. considering that the controller is responsible for initializing the view with appropriate data and handling view's events, data binding mechanism in ExtJS can solve the first part (initializing the view) which is described at View Models and Data Binding, the second part (handling view's events) can be solved with general methods in the controller, every element in the view should send its event to some specific methods and the methods based on the parameters should decide what to do.
This approach makes your methods in the controller a little fat and complicated that is the price of having dynamic form.
It is worth to mention that EXTJS raises different events in the life cycle of controllers and views and you should take benefit of them to manage your dynamic form.
I don't know about Touch, but in ExtJS, I usually do it by using the add function of a fieldset. You just loop through all your records, and create the fields on the fly.
var field = Ext.create('Ext.form.field.Text'); //or Ext.form.field.Date or a number field, whatever your back end returns.
Then set correct config options on field then
formFieldset.add(field);

Sencha Touch 2 Add and Remove textfield inside fieldset

i have strange issue with removing item from fieldset. my app success adding new textfield fieldset item, buth when i do remove() my app screen got stuck without any error on my google chrome.
here my source
view js
Ext.define('qms.view.QC23', {
extend: 'Ext.form.FormPanel',
alias: 'widget.QC23View',
id: 'QC23View',
requires: ['Ext.form.FieldSet', 'Ext.Label'],
config: {
items: [
{
xtype: 'fieldset',
//defaults: { labelAlign: 'top' },
Id:'defectAdd',
layout:{
},
items: [
{
xtype: 'button',
text: 'New Defect',
id: 'DefectQC23Button',
ui: 'action'
},
{
xtype: 'button',
text: 'Remove Defect',
id: 'RemoveQC23Button',
ui: 'action'
}
]
}
]
}
and my controler
Ext.define('qms.controller.QC23con', {
extend: 'Ext.app.Controller',
config: {
refs: {
addDefectButton:'#DefectQC23Button',
rmDefectButton:'#RemoveQC23Button'
},
control: {
addDefectButton:{
tap: 'addDefect'
},
rmDefectButton:{
tap: 'removeDefect'
},
}
},
addDefect: function(button){
button.up('fieldset').add({
xtype: 'textfield',
name: 'MyField-' + button.up('fieldset').length
});
//Ext.getCmp('defectAdd').doLayout();
},
removeDefect: function(button){
button.up('fieldset').remove(button.up('fieldset').items.items[0]);
}
the function for adding item work fine, but when i remove the item my screen stuck. i am using google chrome for testing.
please give me solution for this issue.
thanks.
I noticed you are not checking for the xtype before removing an item from the fieldset. The code might be removing the button itself in which case it might cause your screen to freeze. I created a simple sencha fiddle https://fiddle.sencha.com/#fiddle/4tf that does what you are trying to accomplish.
replace the removeDefect function with this:
var lastItem = button.up('fieldset').items.items.length-1;
if(button.up('fieldset').items.items[lastItem].xtype ==='textfield')
button.up('fieldset').remove(button.up('fieldset').items.items[lastItem]);

sencha touch tap on search button and load a dataview with ajax search

I am almost new to sencha touch and I have this simple question:
I have a panel with a search field and a start search button (a simple search):
items: [{
xtype: 'container',
html: '<div style="width:100%;text-align:center;"><img src="images/logo.png" style="max-width:40%;" /></div>',
},{
xtype: 'fieldset',
title: '<center>Insert your adress</center>',
cls:'ps-red',
items: [{
xtype: 'textfield',
name: 'adress',
required: true,
clearIcon: true,
}]
},{
xtype:'button',
text:'Search',
ui:'confirm-round',
margin:5,
handler:function(){
}
}]
Clicking on the search button I need to make an ajax call with the input text params, and display results to another panel. What should I write in the handler function of the button?
Ext.define('Demo.view.SearchResults', {
extend: 'Ext.Container',
xtype: 'resultcard',
config: {
layout:'fit',
cls:'ks-basic',
items: [{
xtype: 'dataview',
scrollable: 'vertical',
cls: 'dataview-basic',
store: '????',
}]
}
});
OK let us assume the store as 'SampleStore'
this is the sample call that you should write in handler function, see if it is useful to you,in this example I added push view, you can update panel if you want
handler : function(){
var navigationView = button.up('navigationview');
Ext.getStore('SampleStore').getProxy().setExtraParam('search',address);
Ext.getStore('SampleStore').load({
callback: function(record, operation, success) {
if(success && record.length) {
// here you can call any other function to update panel
navigationView.push({
xtype : 'resultcard',
record : record
});
} else {
Ext.Msg.alert('Address not found. (' + address + ')');
}
}
});
}// handler close

How to have the slide multiple screens in Sench touch

I am developing an application in which when submit button is clicked in the form, it should go to a different screen. However it is just printing the results outside of the window and not really going to a new screen. I have hardcoded the store to make sure there is data when I start the application and it still prints it outside of the viewable area.
Here is my Ext.data.Store:
var store = new Ext.data.Store({
model: 'jobSummary',
storeId: 'jobStore',
data : [{title: 'This is test'},
{title: 'This is test2'},
{title: 'This is test3'}]
});
Here is the list that I am using it in:
SearchJobsForm.jobsList = Ext.extend(Ext.Panel, {
dockedItems : [ {
xtype : 'toolbar',
title : 'WTJ',
dock : 'top',
items : [ {
xtype : 'button',
text : 'Back',
ui : 'back',
handler : function() {
//back button controller
},
scope : this
} ]
} ],
items : [ {
xtype : 'list',
emptyText : 'No data available.',
store : 'jobStore',
itemTpl : '<div class="list-item-title">{title}</div>'
+
'<div class="list-item-narrative">{narrative}</div>',
onItemDisclosure : function(record) {
},
grouped : false,
scroll : 'vertical',
fullscreen : true
} ],
initComponent : function() {
SearchJobsForm.jobsList.superclass.initComponent.apply(this, arguments);
}
});
And i am calling this list panel from my submit button handler which is:
var jobsList = new SearchJobsForm.jobsList();
The full code I have pasted on this link for better visibility:
http://pastebin.com/a05AcVWZ
Ok,
SearchJobsForm.form is your main panel, it will contains two components a searchForm (with text/select input) and a panel/list of results.
In the callback, we will hide() the form and show() the results list. This is not a clean code, but the simpliest and kissest one I can get from yours.
First let's instantiate the jobsList
// It has the id ( id: 'jobsListId')
var jobsList = new SearchJobsForm.jobsList();
then you should put all your inputs into a form (xtype : formpanel,
id: 'searchFormId')
And add the resultPanel just after the form
Here is the code
SearchJobsForm.form = Ext.extend(Ext.Panel,{
initComponent: function(){
Ext.apply(this, {
id: 'searchForm',
floating: true,
width: 250,
height: 370,
scroll: 'vertical',
centered: true,
modal: true,
hideOnMaskTap: false,
items: [
{
xtype: 'formpanel', // 1. this is the added formpanel
itemId: 'searchForm',
id: 'searchFormId', // this id is important
items: [
{
xtype: 'textfield',
...
}, {
xtype: 'textfield',
...
},
// all your inputs
]
},
// 2. add here the results panel : jobsList
jobsList
], // the code continues inchanged
dockedItems: [{
...
- Finally we will modify the ajax callback to hide/show the panels. Do not remove one of them, elsewhere you won't be able to reset your form
// here it comes
Ext.util.JSONP.request({
url: "http://"+serverAdd+":"+ port+"/users/searchresults.json",
format: 'json',
callbackKey: 'callback',
params : searchCriteria,
callback: function(data) {
console.log('callback');
// Call your list-filling fonctions here
// jobsList.fill(data);
Ext.getCmp('searchFormId').hide();
Ext.getCmp('jobsListId').show();
},
failure: function ( result) {
console.error('Failed');
}
});
For your next projects, I recommend you to work with classes and namespaces to avoid 1000 lined files ; Ext.ns() is your best friend and will avoid you a lot of headaches.

Categories

Resources