pass parameter to action property from view in sencha touch - button

I have a button inside a view and I have set a action property of it so that I can listen to its tap event in controller as follows
view code
{
xtype:'button',
text:'SKIP',
action:'skip'
}
controller code
onSkipContact:function(){
console.log('tap');
}
now what I want to pass the parameter to onSkipContact action something like as follows
{
xtype:'button',
text:'SKIP',
action:'skip(data.index)' //i want to pass the index of record to the controller
}
so that I can read in controller as follows
onSkipContact:function(index){
console.log('tap' + index );
}
panel containing cv
Ext.define('ca.view.ContactInfoPanel',{
extend:'Ext.Panel',
xtype:'contactinfopanel',
requires: [ 'ca.view.ContactInfo','ca.view.ContactVote'],
config:{
layout:'vbox',
defaults: {
margin: '10 10 10 10'
} ,
items:[{
xtype:'contactinfo'
},{
xtype:'contactvote', // its a CV
}]
},
initialize:function(){
this.callParent();
}
});
here is the contactvote i.e. cv
Ext.define("ca.view.ContactVote",{
extend:'Ext.Container',
xtype:'contactvote',
requires:['Ext.Button'],
config:{
bottom:0,
width: '100%',
defaults: {
margin: '10 20 0 0'
} ,
items:[{
xtype:'button',
text:'SKIP',
action:'skip',
id:'skipbtn'
}]
},
initialize:function(){
console.log(this.data);
this.callParent();
}
});

First, store the data you want to pass to the handler method in the button itself. For example:
{
xtype: 'button',
text: 'SKIP',
action: 'skip',
// Give it the name you want, just ensure it won't
// overlap a property defined by Ext.
dataIndex: data.index
}
Ext event listeners are always passed the event source (in your case the button) as their first argument. So in your handler, you can access your data this way:
onSkipContact: function(button) {
var index = button.index;
console.log('tap' + index);
}

Try this, Set the index in button configuration
{
xtype:'button',
text:'SKIP',
action:'skip',
index : data.index
}
In controller action
onSkipContact:function(button){
// You can get index config like this
console.log('tap' + button.index );
}
I assumed that your have something like following configuration in controller
refs: {
skipBtn : 'button[action=skip]'
},
control: {
skipBtn : {
tap: 'onSkipContact'
}
}
Update
Try
this.getCv().down('button[action=skip]').index = record.data.index;
instead of
this.getCV().setData(record.data)
your button code remain
{
xtype:'button',
text:'SKIP',
action:'skip'
}

Related

ExtJS 6.01 How to update tpl after store loaded

Let's say I have a component with tpl in HTML format, which has a variable named testname, default value is null.
A listener of beforerender calls to a function in viewController, and in this function, I need to load a store and a callback function to update the variable testname in the view, based on the store record returned.
The problem I met is the order of code execution. The function in the viewController always ended first before the store.load callback get executed. Therefore the front view will never get updated. I have tried to setup the asynchronousLoad to false but it doesn't help.
Here is the code in the viewController.
onViewRendering: function(theView) {
console.log('setp 1');
var theStore = Ext.create('App.store.Test');
theStore.load({
asynchronousLoad: false,
callback: function(record) {
console.log('setp 2');
if (record) {
theView.data.testname = 'updated';
}
}
});
console.log('setp 3');
}
Console log displays in step 1, 3, 2.
And here is the code in the View:
Ext.define('App.view.TestView', {
extend: 'Ext.component',
data:{
testname:null
},
tpl:'<p>{testname}</p>',
listeners: {
beforerender: 'onViewRendering'
}
})
Here is the store code:
Ext.define('App.store.Test', {
extend: 'Ext.data.Store',
alias: 'store.test',
autoLoad: true,
remoteFilter: true,
fields: ['id', 'name'],
proxy: {
type: 'direct',
directFn: 'test.getTest'
}
})
I am new to Extjs and really need some help here, thanks in advance!
To update tpl after store load, you have to call setData method like below:
Code snippet:
onViewRendering: function(theView) {
console.log('setp 1');
var theStore = Ext.create('App.store.Test');
theStore.load({
asynchronousLoad: false,
callback: function(record) {
console.log('setp 2');
if (record) {
theView.setData({testname: 'updated'}); //setData method
}
}
});
console.log('setp 3');
}

Displaying name and selecting id on select for Twitter Typeahead

I am trying to implement twitter typeahead into my project, having remote as the source. I am able to make the connection between the front end query text and the sql. The return response looks like this:
[
{
id: 1,
name: 'user one'
},
{
id: 2,
name: 'user two'
}
..
]
The typeahead displays the matching items but it includes the id along with the names in the selection, instead of just the name. Second, I want to get the id value on select but the :select always gives the name value instead of the id.
here is my code:
var source = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url:"{{ path('user_typeahead') }}"+'?string=%QUERY', // twig path
wildcard: '%QUERY',
filter: function (results) {
// Map the remote source JSON array to a JavaScript object array
return $.map(results, function (result) {
return {
value: result
};
});
}
}
});
// Initialize the Bloodhound suggestion engine
source.initialize();
$('#typeahead').typeahead(null, {
display: 'value',
source: source.ttAdapter(),
limit:5,
highlight: true,
hint: true
});
$('#typeahead').bind('typeahead:select', function(ev, suggestion) {
console.log(suggestion);
});
Try this,
Display should be set to the property of the json object. display: 'id'
Chain the custom event. Access your id from suggestion.id.
$('#typeahead').typeahead(null, {
display: 'id',
source: source.ttAdapter(),
limit:5,
highlight: true,
hint: true
}).bind('typeahead:select', function(ev, suggestion) {
console.log(suggestion);
});

Bind constraints in Input control of SAPUI5

My rest service expose me a group of fields: each filed has a value and a list of attributes: enabled, maxLength (in case of string), minLength (in case of string), decimals (number of decimal digits - in case of float).
In OpenUi5 I have:
value and enabled are properties of Input control Link (Good!! I can bind properties with model contains the attributes)
maxLength and decimals are optionsof String type and Float type (Link) but I can't bind options with a model :-/
minLength I can't find a property/option
I would like map (bind) each attribute with component so that automatically the library control for me without writing more code.
there is a property called maxLength for Input Control.
So the only problem I see is binding minLength and decimals for which there is little bit effort is needed.
Solution
Create your own input control by extending the existing Input
Control.How to achieve it?
Sample Code Structure:
jQuery.sap.require("sap.m.Input");
jQuery.sap.declare("sap.m.ComplexInput");
sap.m.Input.extend("sap.m.ComplexInput", {
metadata: {
properties: {
minLength: {
type: "int"
},
decimals: {
type: "int"
},
events: {
//define your own events like checkMinLength,checkDecimals
}
},
onInit: function () {
//on init do something
},
onAfterRendering: function () {
//called after instance has been rendered (it's in the DOM)
},
_somePrivateMethod: function () {
/*do someting...*/
},
somePublicMethod: function () {
/*do someting...*/
},
}
});
sap.m.ComplexInput.prototype.exit = function () {
/* release resources that are not released by the SAPUI5 framework */
//do something
};
Adding CustomData and using wherever you want to.
Then you can access custom data in validation process or on liveChange or so..
Bind the other properties to the value of customData
var input = new sap.m.Input({
value: '{value}',
enabled: '{enabled}',
maxLength: '{maxLength}',
customData: [
new sap.ui.core.CustomData({
key: 'minLength',
value: '{minLength}'
}),
new sap.ui.core.CustomData({
key: 'decimals ',
value: '{decimals}'
})
],
change: function(oEvent) {
var src = oEvent.getSource();
var minLen = src.getCustomData()[0].getValue();
var decimals = src.getCustomData()[1].getValue();
if (src.getValue() && src.getValue().length > minLen) {
src.setValueState('Success');
} else {
src.setValueState('Error');
}
}
});

ExtJS - How to get addCls() and removeCls() to show changes

I am trying to dynamically set the padding on a grid panel I have showing some data. On the event that my checkbox was clicked, it should apply the padding cls.
Here is the relevant ExtJS code:
var permissionsGrid = Ext.create('Ext.grid.Panel', {
//...
items: [{
xtype: 'checkbox',
name: 'EditRoles',
boxLabel: 'Edit User Roles',
handler: function(field, value) {
userRoleFilter = '';
permissionsGrid.removeCls('permissions_panel_nopadding');
console.log(permissionsGrid.hasCls('permissions_panel_nopadding'));
permissionsGrid.addCls('permissions_panel_padding');
console.log(permissionsGrid.hasCls('permissions_panel_padding'));
}
}],
//...
});
Here is my CSS
.permissions_panel_nopadding {
padding: 0px;
}
.permissions_panel_padding {
padding: 5px;
}
When the checkbox is clicked, currently nothing happens. I tried to use:
permissionsGrid.getView().refresh();
...but to no prevail.
You are always removing one class and always adding another class. You need to "switch" the classes. If you don't need special styling when the checkbox isn't clicked, you should add/remove only one class.
handler: function(field, value) {
userRoleFilter = '';
if ( value === true) {
permissionsGrid.removeCls('permissions_panel_nopadding');
permissionsGrid.addCls('permissions_panel_padding');
}
else {
permissionsGrid.addCls('permissions_panel_nopadding');
permissionsGrid.removeCls('permissions_panel_padding');
}
console.log(permissionsGrid.hasCls('permissions_panel_padding'), permissionsGrid.hasCls('permissions_panel_nopadding'));
}
Here is my fiddle with basic panel and only one CSS class: https://fiddle.sencha.com/#fiddle/ne3
EDIT:
ExtJS 6.0+
Since ExtJS 6.0.0, you can use the toggleCls method:
handler: function(field, value) {
permissionsGrid.toggleCls('permissions_panel_padding', value);
permissionsGrid.toggleCls('permissions_panel_nopadding', !value);
console.log(permissionsGrid.hasCls('permissions_panel_padding'), permissionsGrid.hasCls('permissions_panel_nopadding'));
}

Simply counting each time a button is clicked - Ext JS

So I have the #add_button in my main app.js:
{ xtype: 'button', text: 'Add', itemId: 'add_criteria' }
I have the controller here that is listens for each click and attempts to add 1 each time the #add_button is clicked:
Ext.define('AM.controller.Add', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'#add_button': {
click: this.add
}
});
},
add: function(btn) {
var count = 0;
if (count <= 3)
{
count++;
console.log('Count is now ' + count;
}
else {
console.log('wut');
}
}
});
The controller is set up properly, however I can't seem to keep a count on the number of times clicked. It's telling me it's 'undefined'. Any ideas?
And yes I've seen the Sencha docs on the 'button' component. I, however am handling the event with a controller.
You are using count as a local variable, and initializing it to 0 every time your button is clicked. You need to make count a member variable of the controller.
Ext.define('AM.controller.Add', {
extend: 'Ext.app.Controller',
init: function() {
this.count = 0;
this.control({
'#add_button': {
click: this.add
}
});
},
add: function(btn) {
if (this.count <= 3)
{
this.count++;
console.log('Count is now ' + this.count);
}
else {
console.log('wut');
}
}
});

Resources