items: [{
rowspan:3,
columnWidth: 0.5,
margin: '10 10 10 10',
xtype: 'fieldset',
title:'SMS',
enableKeyEvents: true,
items: [{
xtype:'textarea',
width: 200,
height: 160,
id: 'content',
value: '',
enableKeyEvents: true,
listeners: {
keyup: function(form, e) {
var cnt2;
var len2;
var han2;
var varCont;
len2 = 0;
han2 = 0;
varCont = this.value;
for( cnt2 = 0 ; cnt2 < varCont.length; cnt2++ ){
if( varCont.charCodeAt(cnt2) > 255 ){
len2 += 2;
han2 += 2;
}else{
len2 ++;
}
}
Ext.getCmp('bytecnt').setValue(len2); //here is problem
}//keyup
}//listener
},{
xtype:'text',
html:"<input id='bytecnt' name='bytecnt' width='20' value='1'>",
width: 200,
height:20
}]
Ext.getCmp() is for looking up components by ID. Since your input field is not a component (but rather, the HTML of a component), but just an HTML element, you could use Ext.get() to retrieve it. But remember, since the input field you're retrieving with Ext.get() isn't a component, setValue() also won't work.
Why, though, are you using xtype: text with an HTML configuration of an text input field? Why not just use xtype: 'textfield' and allow Ext JS to manage that stuff for you? You can still configure everything else you need on it, but then be able to interact with it as a component.
Related
I'm using ExtJS to show an barcode image. I wanna print that image using the print dialog after do click in a button.
I have a function like this:
function barcode_impr(pkIdGuess){
var win = new Ext.Window({
title: 'Barcode',
layout: 'fit',
autoScroll: true,
y: 120,
width: 300,
height: 300,
modal: true,
closeAction: 'hide',
items:
[{
xtype: 'panel',
//height:'100px',
docked: 'bottom',
html: 'Here goes an image...',
scrollable: true,
renderTo: document.body,
id: 'panel_print',
tools: [{
type: 'print',
handler: function() {
window = Ext.getCmp('panel_print');
window.print();
}
}]
}]
});
win.show();
}
but that show all not only the panel content. What am I doing wrong?
I have made a function doPrint with 2 parameters pnlId (the id of the panel in which your bar code image is placed) and win (the window reference)
We can use this function like below:-
doPrint('panel_print', win);
This function creates an iframe and print the content which we want and then it destroy the iframe.
Working example
Code snippet:-
function doPrint(pnlId, win) {
var pnl = Ext.getCmp(pnlId);
var iFrameId = "printerFrame";
var printFrame = Ext.get(iFrameId);
if (printFrame == null) {
printFrame = Ext.create('Ext.Component', {
id: iFrameId,
autoEl: {
tag: "iframe"
}
});
printFrame.addCls('x-hidden');
win.add(printFrame);
}
var cw = printFrame.el.dom.contentWindow;
// get the contents of the panel and remove hardcoded overflow properties
var markup = pnl.body.dom.innerHTML;
while (markup.indexOf('overflow: auto;') >= 0) {
markup = markup.replace('overflow: auto;', '');
}
var str = Ext.String.format('<html><head>{0}</head><body><img src="resources/images/gabar-logo.gif">{1}</body></html>', '', markup);
// output to the iframe
cw.document.open();
cw.document.write(str);
cw.document.close();
// remove style attrib that has hardcoded height property
// cw.document.getElementsByTagName('DIV')[0].removeAttribute('style');
// print the iframe
cw.print();
// destroy the iframe
Ext.fly(iFrameId).destroy();
};
Hope this will help.
I have a problem with a selection in OnDemandGrid( dojo 1.12.1) and I need some help.
A part of my grid is hidden on creation and this makes the selection 'single' works weird, the selection is active only on visible part of the content. While I scroll I have no more the highlight on my row img1.
However if I apply a sort on a column, the content is refreshed and the whole row becomes selectable.
The example on this page works for EnhancedGrid in selectionMode: 'single' without bugs on a hidden part of a content after loading.
https://dojotoolkit.org/reference-guide/1.10/dojox/grid/EnhancedGrid/plugins/Selector.html, any ideas how to acheve it?
What could I do while creating OnDemandGrid to resolve the problem? I've tried to put a css parameter box-sizing: border-box, but it didn't help me.
There are some simular issues for enchancedgrid, but the solition isn't good for me, maybe it's because I'm using the OnDemandGrid (
dojo EnchancedGrid items do not select programmatically in invisible part of the view)
require([
...
'dojo/store/Memory',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dgrid/extensions/ColumnResizer',
'dgrid/extensions/DijitRegistry'
], function (Memory, OnDemandGrid, Selection, ColumnResizer, DijitRegistry ) {
var columNs = {First_Name: {label: 'First Name'},
Last_Name: {label: 'Last Name'},
hello: {label: 'hello'},
age: {label: 'age'},
size: {label: 'size'},
name: {label: 'name'},
code: {label: 'code'},
id: {label: 'id'},
mdp: {label: 'mdp'},
username: {label: 'username'},
grid: {label: 'grid'}
};
var store = new Memory({ data: createData() });
var CustomGrid = declare([OnDemandGrid, Selection, ColumnResizer, DijitRegistry]);
var grid = new CustomGrid({
selectionMode: 'single',
cellNavigation: false,
store: store,
columns: columNs
}, 'grid');
grid.startup();
function createData() {
var data = [];
var column;
var i;
var item;
for (i = 0; i < 50; i++) {
item = {};
for (column in { First_Name: 1, Last_Name: 1, hello: 1, age: 1, size: 1, name: 1, code: 1, id: 1, mdp: 1, username: 1, grid: 1 }) {
item.id = i;
item[column] = column + '_' + (i + 1);
}
data.push(item);
}
return data;
}
});
//css
.dgrid {
height: 25em !important;
width: 100%;
}
.dgrid .dgrid-scroller {
margin-top: 24px !important;
}
.dgrid-cell {
width: 70px !important;
}
.dgrid-column-set-scroller {
display: inline-block;
overflow-x: auto;
overflow-y: hidden;
}
I could not reproduce your problem. See on the fiddle here.
One difference in that I replaced dojo/store/Memory, which was giving me an error (if you don't get this error maybe you are using a dgrid version older that 0.4 ?), with dstore/Memory.
Then the fiddle is using dojo 1.12.2 (should make no difference with 1.12.1), and dgrid / dstore 1.1.0 (that could explain the difference if you are using a significantly older version). It also uses dijit's claro.css & dgrid's dgrid.css. See below (extracted from the jsfiddle) the part of your source code that I modified:
require({
packages: [
{
name: 'dgrid',
location: '//cdn.rawgit.com/SitePen/dgrid/v1.1.0'
},
{
name: 'dstore',
location: '//cdn.rawgit.com/SitePen/dstore/v1.1.0'
}
]
},[
"dojo/_base/declare",
'dstore/Memory',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dgrid/extensions/ColumnResizer',
'dgrid/extensions/DijitRegistry'
], function (declare, Memory, OnDemandGrid, Selection, ColumnResizer, DijitRegistry ) {
I am using inline editing of enhancedgrid cells and have a NumberSpinner element. The constraints of this numberspinner don't work when editing inline. The required property works fine though.
My code:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, editorParams:{constraints:{ min:-1000, max:1000, places:0 }} }}
I have also tried:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, constraints:{ min:-1000, max:1000, places:0 } }}
There is an easier solution, guys:
constraint:{min:0,max:24}
{field: "hours", name: "Stunden",type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, constraint:{min:0,max:24}, widgetProps: {smallDelta:0.25, intermediateChanges:true,}},
It has to be outside of widgetProps and in singular...
I don't know what version of Dojo you use, but there is known bug in 1.6 that constraints are ignored in grid widgets. However, I solve that problem doing a little overwriting standard NumberSpinner.
dojo.require("dijit.form.NumberSpinner");
dojo.addOnLoad(function() {
dojo.declare("mySpinner", [ dijit.form.NumberSpinner], {
validator: function(v, c){
var MIN= -1000;
var MAX = 1000;
c.min= MIN;
c.max = MAX ;
return ((v < MAX ) && (v > MIN));
},
});
var dateBox = new mySpinner({}).placeAt('foo');
dateBox.set("value", 1000);
});
(Now, in your grid structure you should use mySpinner of course, and it should do the trick).
Demo: http://jsfiddle.net/tvUaK/135/
I used another way to solve that problem. I define the type of cell as Widget and then I create the widget on get method.
{
field: 'msorder',
width: '10%',
name: 'Milestone Order',
editable: true,
type: dojox.grid.cells._Widget,
get: function(rowIndex, item) {
var store = this.grid.store,
value = store.getValue(item, 'value');
this.widget = new dijit.form.NumberSpinner({ value:0,
constraints:{ min:-1000, max:1000 }
});
return value;
}
}
With this implementation I was able to set different constraints for each cell on the grid.
I've just finished creating a meticulously generated grid of icons (imageViews) and now I need to be able to do something with them. What I'm finding, though, is that the event listener I'm trying to bind isn't getting bound. Window loads, my icons are displayed nicely, but they aren't clickable.
Can anyone see what I'm missing? The code below is a fully functional (except for the part that doesn't function) file. You should be able to copy it into a test app and load it right up (may be iPhone-only at the moment).
Any insight would be much appreciated.
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Ti.UI.setBackgroundColor('#000');
//
// create base UI tab and root window
//
var win = Ti.UI.createWindow({
backgroundColor:'#fff',
layout: 'vertical',
navBarHidden: true,
});
// icon grid
var icons = [
{ image: '/images/ico_generic.png', label: 'Hospital Locations', url: 'http://google.com' },
{ image: '/images/ico_generic.png', label: 'Tobacco Free Campus', url: 'http:://robwilkerson.org' },
{ image: '/images/ico_generic.png', label: 'ER Wait Times', url: 'http://letmegooglethatforyou.com' },
{ image: '/images/ico_generic.png', label: 'Make a Donation', url: 'http://flickr.com/photos/robwilkerson' },
{ image: '/images/ico_generic.png', label: 'Condition Search', url: 'http://facebook.com' },
{ image: '/images/ico_generic.png', label: 'Video Library', url: 'http://google.com/reader' },
{ image: '/images/ico_generic.png', label: 'Financial Help', url: 'http://stackoverflow.com' },
{ image: '/images/ico_generic.png', label: 'Patient Forms', url: 'http://github.com' }
];
// put the grid in a scrollable view
var iconGrid = Ti.UI.createScrollView({
layout: 'vertical',
});
// incoming properties we want customizable
var cols = 3;
var icoW = 57;
var icoH = 57;
// Grid
var xSpacer = 10; // horizontal space b/t icons
var ySpacer = 10; // vertical space b/t icons
var rows = Math.ceil( icons.length / cols ); // how many rows?
// Container width = 1/3 of the viewport minus the icon widths and spacers
var containerW = Math.floor( ( Ti.Platform.displayCaps.platformWidth - ( xSpacer * ( cols + 1 ) ) ) / 3 );
// Container height = icon height + label spacer + label height
var containerH = icoH + ySpacer + 15;
// Row height = icon height + top spacer + bottom spacer + label spacer + 15 (label height)
var rowH = containerH + ( 2 * ySpacer );
// Incrementing values
var i = 0;
var viewHeight = 0;
for( var y = 0; y < rows; y++ ) {
var thisRow = Ti.UI.createView({
className: 'grid',
layout: 'horizontal',
height: rowH,
touchEnabled: false,
});
viewHeight += rowH;
for( var x = 0; x < cols && i < icons.length; x++ ) {
var container = Ti.UI.createView({
left: xSpacer,
height: containerH,
top: ySpacer,
width: containerW,
});
var icon = Ti.UI.createImageView({
left: ( containerW - icoW ) / 2,
height: icoH,
image: icons[i].image,
top: 0,
width: icoW,
});
var label = Ti.UI.createLabel({
// borderColor: '#00f',
font: { fontSize: 12 },
height: 15,
text: icons[i].label,
textAlign: 'center',
top: icoH + ySpacer,
width: containerW,
});
icon.addEventListener( 'click', function( e ) {
alert( 'Icon ' + i + ' was clicked' );d
});
container.add( icon );
container.add( label );
thisRow.add( container );
i++;
}
iconGrid.add( thisRow );
iconGrid.height = viewHeight;
}
win.add( iconGrid );
win.open();
You can also apply an event listener to the "view" itself. The reason being is, if you constantly add the same event listener to every single view, you'll cause the device's memory to become smaller and smaller, especially in cases where you'll have a larger data set.
My suggestion to you is this:
Add your own property to the imageView, like an "id" or something. So something like:
Ti.UI.createImageView({image: 'path/to/image.png', id: 'array_key'});
Once you've done that, you can add an event listener to the parent view, in this case your imageView.
view.addEventListener('click', function(e) {
alert(e.source.id + ' was clicked');
});
That way you have one event listener that can handle all the imageView events.
This one's on me. In my learning process, I went through a couple of different solutions to display a grid of icons. In one of the early iterations, I had to disable touch for the row (it was a tableView attempt). Several iterations later I got the display right, but disabling touch access on the row killed my ability to "click" the icons.
I was so far down the road that I didn't even realize that property was still in place until a new set of eyes pointed it out to me. Once I removed that property on thisRow, the event listeners got bound properly.
I am adding some line of code. What I have done is like created the grid of images and when you click, you will be able to that image.
{
"body": [
{
"type": "photo",
"order": 1,
"photos": [
{
"thumbnail": "http://www.flower.com/version_2.0/files/photos/thumbnails/745178756-_-1331130219.jpg",
"photo": "http://www.flower.com/version_2.0/files/photos/745178756-_-1331130219.jpg"
},
{
"thumbnail": "http://www.flower.com/version_2.0/files/photos/thumbnails/58062938-_-1337463040.jpg",
"photo": "http://www.flower.com/version_2.0/files/photos/58062938-_-1337463040.jpg"
},
{
"thumbnail": "http://www.flower.com/version_2.0/files/photos/thumbnails/1368715237-_-1337463149.jpg",
"photo": "http://www.flower.comversion_2.0/files/photos/1368715237-_-1337463149.jpg"
},
]
},
],
"status": true
}
It was response I was getting from the server.
Now for Making it is in grid and for clickable image, I am going to paste the code below. Note grid is done for 320 px width.
var xhr = Ti.Network.createHTTPClient({
onload : function(e) {
var response = JSON.parse(this.responseText);
var myObjectString = JSON.stringify(response);
Titanium.API.info('myObjectString--->: ' + myObjectString)
var myArray = response.body;
var objectArray = [];
var k = 5;
for (var i = 0; i < myArray[0].photos.length/5; i++) {
var l = 0+i*5; var m = 0 for (var j = l; j < k; j++) {
var thumb = Ti.UI.createImageView({
image:myArray[0].photos[j].thumbnail,
largeImage:myArray[0].photos[j].photo,
height:60,
tag:j,
width:60,
top:5*(i+1)+60*i,
left:3*(m+1)+60*m,
});
objectArray.push(thumb);
m++;
scroll.add(thumb);
thumb.addEventListener('click' ,function(e)
{
for(var i =0;i<objectArray.length;i++)
{
if(e.source.tag==objectArray[i].tag)
{
var LargeImageView = Ti.UI.createWindow({
backButtonTitle:'Image',
barColor:'#000',
backgroundColor: '#fff',
backgroundImage:'./Images/background.png',
url:'/More/DetailsImage.js',
image:objectArray[i].largeImage,
ImageArray:objectArray,
index:i,
});
Titanium.UI.currentTab.open(LargeImageView,{animated:true,modal:true});
break;
}
}
}); } l=k+5; k=k+5;
} } });
I have created a Pie chart using the Pie chart example in sencha ExtJS website , I wanted to add a click event to the each Pie slice so that i get handle to the contextual data on that slice. I was able to add a click listener to the Pie but not sure how to get the data on the slice.
Below is the ExtJS code.
Ext.onReady(function(){
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [{
'name': 'January',
'data1': 10
}, {
'name': 'February',
'data1': 7
}, {
'name': 'March',
'data1': 5
}, {
'name': 'April',
'data1': 2
}, {
'name': 'May',
'data1': 27
}]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 800,
height: 600,
animate: true,
store: store,
theme: 'Base:gradients',
legend: { // Pie Chart Legend Position
position: 'right'
},
series: [{
type: 'pie',
field: 'data1',
showInLegend: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item){
//calculate and display percentage on hover
var total = 0;
store.each(function(rec){
total += rec.get('data1');
});
this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100) + '%');
}
},
highlight: {
segment: {
margin: 5
}
},
label: {
field: 'name',
display: 'rotate',
contrast: true,
font: '18px Arial'
},
listeners: {//This Doesnt Work :(
itemclick: function(o){
alert('clicked at : ' + o);
}
}
}],
listeners: { //This Event handler works but I am not sure how to figure how which slice i have clicked ..................................
click: {
element: store, //bind to the underlying el property on the panel
fn: function(o, a){
alert('clicked' + o + a + this);
}
}
}
});
});
Kindly help.
Regards,
Lalit
Here is how you get data of the clicked slice. The series class supports listeners via the Observable syntax and they are:
itemmouseup When the user interacts with a marker.
itemmousedown When the user interacts with a marker.
itemmousemove When the user iteracts with a marker.
afterrender Will be triggered when the animation ends or when the series has been rendered completely.
I will make use of the itemmousedown event to capture the clicked slice. Here is my listener method:
series: [{
.
.
.
listeners:{
itemmousedown : function(obj) {
alert(obj.storeItem.data['name'] + ' &' + obj.storeItem.data['data1']);
}
}
.
}]
Note that I have placed my listener inside the series and not the chart! Now, the obj variable holds lot of information. For each series, the property to get data will differ. So, you will have to carefully inspect the object using firebug or some other developer tool.
Now, in case of Piecharts, you can get the slice information by using the obj:
obj.storeItem.data['your-series-variable-name']
Here is the obj from firebug..
I'm using a more selective approach, because I needed to add some custom logic in order to implement drag-and-drop for our charts. So after the chart definition I just add the following:
// Add drag-and-drop listeners to the sprites
var surface = chart.surface;
var items = surface.items.items;
for (var i = 0, ln = items.length; i < ln; i++) {
var sprite = items[i];
if (sprite.type != "circle") { continue; } // only add listeners to circles
// Additional funky checks for the draggable sprites
sprite.on("mousedown", onSpriteMouseDown, sprite); // mouse down ONLY for sprites
}
surface.on("mousemove", onSurfaceMouseMove, surface); // mouse move for the entire surface
surface.on("mouseup", onSurfaceMouseUp, surface);
Cheers!
Frank