In ExtJS, How to inject enableKeyEvents = true in component? - events

This is my code,
myText.enableKeyEvents = true; // **
myText.on('keyup', function(t){ console.log(t.getValue()); });
It not work, I think it may has some invoke method.
Any one has an idea ?
Full code
// function
var txfJump = function(txf){
var next = txf.nextSibling();
if(next.xtype == 'textfield'){
txf.enableKeyEvents = true;
txf.on('keyup', function(t, e){
if(t.getValue().length == t.maxLength){
next.focus();
}
});
txfJump(next);
}
};
// form
var p = new Ext.Panel({
title : 'test panel',
width : 400,
defaults: {
xtype : 'textfield',
},
items : [
{ ref : 'one', maxLength : 5 },
{ ref : 'two', maxLength : 5 },
{ ref : 'three',maxLength : 5 },
{
xtype : 'button',
text : 'SAMPLE'
},
{ ref : 'four', maxLength : 5 },
],
renderTo: Ext.getBody()
});
Ext.onReady(function(){
txfJump(p.one);
});

It's not possible without hackish tricks. Having read the TextField's source, i found out, that there is a private method initEvents, that sets up the callbacks for the html-elements if and only if enableKeyEvents is set. So, changing enableKeyEvents after initEvents was called has no effect, until it is called again.
To inject it, one could try to trigger a re-rendering of the component, or one could copy the behaviour of the relevant parts of TextField's initEvent. But there doesn't seem to be an official way.

you have to call txf.initEvents(), this needs to be called after txf.enableKeyEvents = true;
var txfJump = function(txf){
var next = txf.nextSibling();
if(next.xtype == 'textfield'){
txf.enableKeyEvents = true;
txf.initEvents(); //<----- this is what you have missing
txf.on('keyup', function(t, e){
if(t.getValue().length == t.maxLength){
next.focus();
}
});
txfJump(next);
}

You should pass "enableKeyEvents": true when getting new Ext.form.TextField instance. Here is the example usage
var textField = new Ext.form.TextField({
. // your configs
.
enableKeyEvents: true,
.
.
})

Related

Hyperloop eventlistener example

I try to make a flac file player with Appcelerator and Hyperloopusing the OrigamiEngine
It works as I can play, pause and stop the player. But I can't get the "addEventListener" mode working. I read some examples and something about the delegate methods. But I'm not a native iOS coder and all my tryings failed.
Can anybody tells me how to code the eventlistener for the didChangeState function?
This is my unfortunately not working code
//Application Window Component Constructor
function ApplicationWindow() {
Ti.Media.audioSessionCategory = Ti.Media.AUDIO_SESSION_CATEGORY_PLAYBACK;
var NSURL = require('Foundation/NSURL');
var ORGMEngine = require('OrigamiEngine/ORGMEngine');
var audioPlayer = new ORGMEngine();
var self = Ti.UI.createWindow({
backgroundColor : '#ffffff'
});
var startStopButton = Ti.UI.createButton({
title : 'Start/Stop Streaming',
top : 100,
width : 200,
height : 40
});
var pauseResumeButton = Ti.UI.createButton({
title : 'Pause/Resume Streaming',
top : 140,
width : 200,
height : 40,
enabled : false
});
self.add(startStopButton);
self.add(pauseResumeButton);
startStopButton.addEventListener('click', function() {
console.log('audioPlayer.currentState: ' + audioPlayer.currentState);
// When paused, playing returns false.
// If both are false, playback is stopped.
if (audioPlayer.currentState == 1) {
audioPlayer.stop();
audioPlayer.release();
pauseResumeButton.enabled = false;
} else {
var url = NSURL.URLWithString('http://faq.fantasticlibrary.de/test.flac');
audioPlayer.playUrl(url);
setTimeout(function(){
console.log(audioPlayer.metadata());
}, 10000);
pauseResumeButton.enabled = true;
}
});
pauseResumeButton.addEventListener('click', function() {
console.log('audioPlayer.currentState: ' + audioPlayer.currentState);
if (audioPlayer.currentState == 1) {
audioPlayer.pause();
} else {
audioPlayer.resume();
}
});
var StateChangeDelegate = Hyperloop.defineClass('MyDelegate', 'NSObject', ['ORGMEngineDelegate']);
StateChangeDelegate.addMethod({
selector: 'engine:didChangeState:',
instance: true,
arguments: ['ORGMEngine', 'ORGMEngineState'],
callback: function (engine, state) {
if (this.didChangeState) {
this.didChangeState(engine, state);
}
}
});
var delegate = new StateChangeDelegate();
delegate.didChangeState = function(ORMEngine,state) {
console.log('does the state change???');
};
self.addEventListener('close', function() {
audioPlayer.stop();
audioPlayer.release();
});
return self;
}
module.exports = ApplicationWindow;
Running demo project to download: http://lightapps.de/files/flactest.zip
Try it:
delegate.on('didChangeState', function(ORMEngine,state){
console.log('does the state change???');
});
I can't test this in the moment, but i think that will work for you.

Table sorter AJAX based column filter [duplicate]

Can you please help me to have table sorter with ajax for individual column.
is there anything inbuilt method to call ajax call for filter column?
My source code is below
theme: 'blue',
widthFixed: true,
widgets: [ 'stickyHeaders', 'columnSelector','filter'],
textExtraction: function(node, table, cellIndex){
return $(node).text().replace(/\s'/g,'');
},
headers: {0: { filter: false},6: { filter: false},7: { filter: false},8: { filter: false}},
widgetOptions : {
// Use the $.tablesorter.storage utility to save the most recent filters
filter_saveFilters : false,
// jQuery selector string of an element used to reset the filters
filter_reset : 'button.reset',
// add custom selector elements to the filter row
filter_formatter : {
/*0 : function($cell, indx){
return $.tablesorter.filterFormatter.uiDatepicker( $cell, indx, {
dateFormat: 'dd/mm/yyyy',
changeMonth: true,
changeYear : true
});
},*/
// Alphanumeric (match)
4 : function($cell, indx){
return $.tablesorter.filterFormatter.select2( $cell, indx, {
match : true, // adds "filter-match" to header
// cellText : 'Select: ', // Cell text
width: '90%', // adjusted width to allow for cell text
value: [<%=createdBy%>], // initial values
placeholder: "Search.."
});
},
5 : function($cell, indx){
return $.tablesorter.filterFormatter.select2( $cell, indx, {
match : true, // adds "filter-match" to header
// cellText : 'Select: ', // Cell text
width: '90%', // adjusted width to allow for cell text
value: [<%=actions%>], // initial values
placeholder: "Search.."
});
},
/*7 : function($cell, indx){
return $.tablesorter.filterFormatter.uiDatepicker( $cell, indx, {
// from : '08/01/2013', // default from date
// to : '1/18/2014', // default to date
dateFormat : 'dd/MM/yyyy',
changeMonth : true,
changeYear : true,
cellText : ""
});
}*/
},
// option added in v2.16.0
filter_selectSource : {
// Alphanumeric match (prefix only)
// added as select2 options (you could also use select2 data option)
4 : function(table, column) {
return [<%=createdBy%>];
},
5 : function(table, column) {
return [<%=actions%>];
},
}
/* filter_placeholder : {
from : 'From...',
to : 'To...'
}*/
},
});
Please help me with above thing
thanks in advance.
If you aren't using the pager widget, then you can bind to the filterStart event. But make sure to add a method to not make another ajax call because the filterStart event will fire again after the table updates. Try something like this (this is untested code):
var $table = $('table');
$table
.on('filterBegin', function( event, filters ){
// only trigger an ajax call if the filters have changed
if ( filters.join(',') !== $table.data('lastSearch').join(',') ) {
// do some ajax stuff here
// then in the success callback, save content to table...
// then update
$table
.find('tbody')
.html( newContent )
.trigger('update');
}
})
.tablesorter({
// add your other options here
widgetOptions: {
// you might need to set this option to prevent
// rows from being hidden... maybe!
filter_serversideFiltering : true
},
initialized: function(){
lastSearch = $table.data('lastSearch');
}
});

Ext js sorting custom column by contents

I have a grid in ext with some custom columns, and I want to be able to sort this column - I want to sort it by what is displayed inside of it, but really I just cannot figure out how to define a sorter for a column that will not be based on the dataIndex - I tried using a custom model, but I could not get that to work.
{
text: 'Parent',
dataIndex: 'Parent',
renderer: function(value, meta, record) {
var ret = record.raw.Parent;
if (ret) {
return ret.Name;
} else {
meta.tdCls = 'invisible';
return record.data.Name;
}
},
sortable: true
},
You should be able to override the doSort method of the column. Here's the gist of it. I also created a working fiddle (http://jsfiddle.net/cfarmerga/LG5uA/). The fiddle uses the string length of a field as the property to sort on, but of course you could apply your own custom sort logic.
var grid = Ext.create('Ext.grid.Panel',{
//...
columns: [
{ text: 'name', dataIndex: 'name', sortable: true },
{
text: 'Custom',
sortable : true,
dataIndex: 'customsort',
doSort: function(state) {
var ds = this.up('grid').getStore();
var field = this.getSortParam();
ds.sort({
property: field,
direction: state,
sorterFn: function(v1, v2){
v1 = v1.get(field);
v2 = v2.get(field);
return v1.length > v2.length ? 1 : (v1.length < v2.length ? -1 : 0);
}
});
}
}
]
//....
});
For Ext JS version 5, it looks like doSort was taken out, so I couldn't override that. Instead, I went the route of listening to the sortchange event, and from there, I used the Ext.data.Store.setSorters method. The code is a bit custom, and overly complex because of the data that I'm using, so keep that in mind (Fiddle here):
// grid class
initComponent: function() {
...
this.on('sortchange', this.onSortChange, this);
},
onSortChange: function(container, column, direction, eOpts) {
// check for dayColumnIndex
if (column && column.dayColumnIndex !== undefined) {
this.sortColumnByIndex(column.dayColumnIndex, direction);
}
},
sortColumnByIndex: function(columnIndex, direction) {
var store = this.getStore();
if (store) {
var sorterFn = function(rec1, rec2) {
var sortValue = false;
if (rec1 && rec2) {
var day1;
var daysStore1 = rec1.getDaysStore();
if (daysStore1) {
day1 = daysStore1.getAt(columnIndex);
}
var day2;
var daysStore2 = rec2.getDaysStore();
if (daysStore2) {
day2 = daysStore2.getAt(columnIndex);
}
if (day1 && day2) {
var val1 = day1.get('value');
var val2 = day2.get('value');
sortValue = val1 > val2 ? 1 : val1 === val2 ? 0 : -1;
}
}
return sortValue;
};
if (direction !== 'ASC') {
sorterFn = function(rec1, rec2) {
var sortValue = false;
if (rec1 && rec2) {
var day1;
var daysStore1 = rec1.getDaysStore();
if (daysStore1) {
day1 = daysStore1.getAt(columnIndex);
}
var day2;
var daysStore2 = rec2.getDaysStore();
if (daysStore2) {
day2 = daysStore2.getAt(columnIndex);
}
if (day1 && day2) {
var val1 = day1.get('value');
var val2 = day2.get('value');
sortValue = val1 < val2 ? 1 : val1 === val2 ? 0 : -1;
}
}
return sortValue;
};
}
store.setSorters([{
sorterFn: sorterFn
}]);
}
}
There is a convert method on the Ext.data.Model class that allows you to convert the data before it's being used. Then you can just specify this 'dataIndex' in your column and do a normal sort. The column will be sorted by that converted value. Here is the a sample model with just one field (Parent) and with it's corresponding conversion:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'Parent', type: 'string', convert: sortParent},
// other fields...
],
sortParent: function(value, record) {
var ret = record.raw.Parent;
if (ret) {
return ret.Name;
} else {
meta.tdCls = 'invisible';
return record.data.Name;
}
}
});

Kendo Treeview Expand Node

I have this treeview wich can have a variable number of children (some nodes can have up to 3 generations of children, some may have only one etc)
What I'm trying to do is expand a certain node when the treeview is loaded. And I have 2 problems:
1) I can't find an event/callback so that I know when the treeview is ready
2) The expand function doesn't always work ( I'll explain )
This is my treeview:
function InitializeTreeview() {
var Children_Merchants = {
transport: {
read: {
url: function (options) {
return kendo.format(websiteRootUrl + '/Merchants/Merchants/?hasParents={0}', hasParent);
}
}
},
schema: {
model: {
model: {
id: "ID",
hasChildren: true,
children: Children_Merchants
}
}
}
};
var Brandowners = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: kendo.format(websiteRootUrl + '/Merchants/GetBrandowners?databaseID={0}', selectedDatabaseID)
}
},
//change: ExpandNode, - if I call expand node like this, it works.
schema: {
model: {
id: "ID",
hasChildren: true,
children: Children_Merchants
}
}
});
$('#treeview').kendoTreeView({
dataSource: Brandowners,
animation: {
collapse: {
duration: 200,
effects: "fadeOut"
},
expand: {
duration: 200,
effects: "fadeIn"
}
},
dataTextField: "Name",
complete: function () { alert('ok'); },
//dataBound : ExpandNode,
select: OnSelect,
expand: CheckIfHasParent
}).data('kendoTreeView');
}
function ExpandNode() {
var treeview;
treeview = $("#treeview").data("kendoTreeView");
var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
treeview.expand(nodeToExpand);
}
The databind works ok, my controllers get called, everything's fine.
So what I tried is hook up the ExpandNode function to a click of a button. The function gets called but nothing happens. BUT if I hook it up to the change event of the parents datasource, it works. Another interesting thing is that the select works so if I replace treeview.expand(...) with treeview.select(...), it works on the click.
So my questions are:
1) What event should I use for loadEnd ( or smth like that ) - so I won't have to bind the function to button click (it's still ok but I preffer on load ended) - P.S. I tried all the ones I found on the kendo forums,like: change, requestEnd, success, dataBound and they don't work. I tried sending the JSON with the property "expanded" set to TRUE, for the node in question, but that only modifies the arrow to show like it's opened, but it doesn't call the controller and load the children.
2) Do you know why ExpandNode works only when binded to the change event? - the most important question to me.
3) If you have suggestions, or have I done something wrong in the initialiation of the treeview, please tell me.
I've copied your code with some free interpretations and the answer your questions is:
What event should I use for loadEnd => dataBound
Do you know why ExpandNode works only when binded to the change event? => No, it works without binding it to change event. If it does not then there is something else in your code.
Suggestions => There is some information missing about your code that might make the difference with what I've implemented.
What is CheckIfHasParent? => I have implemented it as a function that actually does nothing.
What is hasParent? => I've ignored it.
The code as I write it:
$(document).ready(function () {
function InitializeTreeview() {
var Children_Merchants = {
transport: {
read: function (op) {
var id = op.data.ID;
var data = [];
for (var i = 0; i < 10; i++) {
var aux = id * 100 + i;
data.push({ Name: "Name-" + aux, ID: aux});
}
op.success(data);
}
},
schema : {
model: {
model: {
id : "ID",
hasChildren: true,
children : Children_Merchants
}
}
}
};
var Brandowners = new kendo.data.HierarchicalDataSource({
transport: {
read: function (op) {
op.success([
{"Name": "Adam", "ID": 1},
{"Name": "Benjamin", "ID": 2},
{"Name": "Caleb", "ID": 3},
{"Name": "Daniel", "ID": 4},
{"Name": "Ephraim", "ID": 5},
{"Name": "Frank", "ID": 6},
{"Name": "Gideon", "ID": 7}
])
}
},
//change: ExpandNode, - if I call expand node like this, it works.
schema : {
model: {
id : "ID",
hasChildren: true,
children : Children_Merchants
}
}
});
$('#treeview').kendoTreeView({
dataSource : Brandowners,
animation : {
collapse: {
duration: 200,
effects : "fadeOut"
},
expand : {
duration: 200,
effects : "fadeIn"
}
},
dataTextField: "Name",
dataBound : ExpandNode,
expand : CheckIfHasParent
}).data('kendoTreeView');
}
function ExpandNode() {
var treeview;
treeview = $("#treeview").data("kendoTreeView");
var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
treeview.expand(nodeToExpand);
}
function CheckIfHasParent(e) {
}
InitializeTreeview();
});
and you can play with it here : http://jsfiddle.net/OnaBai/dSt2h/
$("#treeview").kendoTreeView({
animation: {
expand: true
},
dataSource: dataSource,
dataBound: function (e) {
var tv = $("#treeview").data("kendoTreeView");
if (tv != null) {
tv.expand(".k-item");
}
},
dataTextField: "test",
dataValueField: "id"
});
For anyone who may be interested:
function ExpandNode() {
var treeview;
var node1;
treeview = $("#treeview").data("kendoTreeView");
var node2;
var myURL = kendo.format(websiteRootUrl + '/Merchants/GetPathForSelectedNode?databaseID={0}&merchantID={1}&brandownerID={2}', selectedDatabaseID,MerID,BowID);
node1 = treeview.dataSource.get(BowID);
node = treeview.findByUid(node1.uid);
var uid = node1.uid;
node.find('span:first-child').trigger('click'); //expand 1st level
$.ajax( {
url: myURL,
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function(result)
{
var length = result.length;
var lastVal = 1;
for (var i = 1; i < length-1; i++) {
$("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
() {
i = lastVal; // have to reinitialize i because waitUntilExist's callback will find the i incermented, over the needed value
lastVal++;
node2 = node1.children.get(result[i]);
node = treeview.findByUid(node2.uid);
uid = node2.uid;
node1 = node2;
if(lastVal <= length-1)
node.find('span:first-child').trigger('click'); // keep expanding
else
{
treeview.select(node); // just select last node
currentSelectedNode = node;
}
});
}
if(length == 2) //select 1st child
{
$("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
() {
node2 = node1.children.get(result[i]);
node = treeview.findByUid(node2.uid);
uid = node2.uid;
node1 = node2;
treeview.select(node); // just select last node
currentSelectedNode = node;
});
}
}
});
}
This is my method. The for loop starts at 1 because the 1st element in my array is the 1st node ID - wich I've already expanded. the .waitUntilExists is Ryan Lester's method (I put a link in the comments above). Many thanks to my colleague, to you OnaBai and, of courese, to Ryan Lester. I hope this helps someone. Cheers
ypu can easily find the treeview is ready for expand by following code which are expanding all the treeview nodes you can also find it by checking perticular id or text
hopw, following example will help you
Ex:
$("#treeview").kendoTreeView({
animation: {
expand: true
},
dataSource: dataSource,
dataBound: function (e) {
var tv = $("#treeview").data("kendoTreeView");
if (tv != null) {
tv.expand(".k-item");
}
},
dataTextField: "test",
dataValueField: "id"
});

jquery plugin creation issue

I have created a plugin with following codes:
var myplugin = {
init: function(options) {
$.myplugin.settings = $.extend({}, $.myplugin.defaults, options);
},
method1: function(par1) {
.....
},
method2: function(par1) {
.....
}
};
$.myplugin = function(method){
if ( myplugin[method] ) {
return myplugin[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if (typeof method === 'object' || !method) {
return myplugin.init.apply(this, arguments);
} else {
$.error( 'Method "' + method + '" does not exist in myplugin!');
}
};
$.myplugin.defaults = {
option1: 'test',
option2: '',
option3: ''
};
$.myplugin.settings = {};
$.myplugin();
This works well but the issue is that when I try to set more than 1 option and try to return its values afterwards, it gives empty; setting one option works well. For eg.
If on changing the first combo box value I call this:
$.myplugin({option1: 'first test'});
it works, but when I try to call another on second combo box it doesn't save the option, instead it reset to empty.
Is there any fix?
I would re-organize the plugin to use this structure:
var methods = {
settings: {
foo: "foo",
bar: "bar"
},
init: function(options) {
this.settings = $.extend({}, this.settings, options);
},
method1: function(par1) {
alert(this.settings.foo);
},
method2: function(par1) {
alert(this.settings.bar);
}
};
function MyPlugin(options) {
this.init(options);
return this;
}
$.extend(MyPlugin.prototype, methods);
$.myPlugin = function(options) {
return new MyPlugin(options);
}
/* usage */
// without parameters
var obj1 = $.myPlugin();
// with parameters
var obj2 = $.myPlugin({foo: "foobar"});
// each has it's own settings
obj1.method1();
obj2.method1();
Demo: http://jsfiddle.net/ypXdS/
Essentially $.myPlugin simply creates and returns a new instance of the MyPlugin class. You could get rid of it completely and use new myPlugin(options) in it's place.

Resources