Creating a simple Sencha component using a loop - javascript

How do we substitute hard-coded data with a for-loop in Sencha ExtJS?
Say, for example I've defined the following list:
Ext.application({
launch: function() {
Ext.create('Ext.List', {
fullscreen: true,
itemTpl: '{title}',
data: [{
title: 'Item 1'
}, {
title: 'Item 2'
}, {
title: 'Item 3'
}, {
title: 'Item 4'
}]
});
}
});
How to replace data to something like this:
Ext.application({
launch: function() {
Ext.create('Ext.List', {
fullscreen: true,
itemTpl: '{title}',
data: [
for(int i=0;i<5;i++){
{title: 'Item '+i},
}
]
});
}
});

This is really basic stuff - I'd recommend you familiarise yourself with the basic language constructs before investing time in a framework. There are several ways you could do this...
see: MDN: A re-introduction to Javascript
Simplest way, create your configuration data first and assign it to a variable:
Ext.application({
launch: function() {
var listData = [];
for(var i=0;i<5;i++)
listData.push({title: 'Item '+i});
Ext.create('Ext.List', {
// ...
data: listData
});
}
});
... or for those times when you're in the global execution scope and you don't want to pollute the window object with unnecessary variables - or just have an OCD over "one-liners" - you could take advantage of an inline function / closure:
Ext.create('Ext.List', {
// ...
data: (function(){
var data = [];
for(var i=0;i<5;i++)
data.push({title: 'Item '+i});
return data;
})()
});
... or on occasion I've used the following because I think it looks neater (but that's subjective):
Ext.create('Ext.List', {
// ...
data: Ext.Array.map(Array.apply(null, Array(5)), function(o,i){
return {title: 'Item '+i};
})
});

Related

How to read values from multiselector component

I am trying to use multiselector from EXTJS 6.5.2
This is the code that I am using to create multiselector with the values that I need
{
xtype: 'multiselector',
title: 'I caktohet:',
name: 'Caktohen[]',
bind: '{userfullname.value}',
fieldName: 'userfullname',
viewConfig: {
deferEmptyText: false,
emptyText: 'Askush i zgjedhur'
},
search: {
field: 'userfullname',
model: 'InTenders.model.UserModel',
store: {
type: 'users',
sorters: 'userfullname',
// proxy: {
// type: 'rest',
// limitParam: null,
// url: 'api/User'
// }
}
}
}
When I call form = win.down('form') records I can get all values except the multiselector values, they show like this on console.
Anyone can help me or guide me how to get the values?
Thank you.
//Code that I'm trying to get multiselector items and save them
saveTenderForm: function (button, e, eOpts) {
var userMultiSelector = Ext.getCmp('AssignedUsers'); //save assigned users
var selectedUsers = userMultiSelector.getStore().getData(); //get store and put them in array
var me = this,
win = button.up('window'),
form = win.down('form'),
// formApplyUpload = this.getFormApplyUpload(),
// var ko = win.items.items[0].items.items[0].value;
recordtenderUsers = Ext.create('InTenders.model.TenderSaveModel');
// recordtenderUsers = form.getRecord();
// record = form.getRecord(),
values = form.getValues();
// appFile = this.getApplicationFile(),
// callbacks;
recordtenderUsers.set(values);
recordtenderUsers.set('tenderUsers',selectedUsers.items);
// // me.showMask();
// if (form.isValid()) {
recordtenderUsers.save({
success: function (recordtenderUsers, operation) {
win.close();
me.hideMask();
},
failure: function (recordtenderUsers, operation) {
me.hideMask();
}
});
You can get value using multiselector.down('grid') this will return you the grid. And grid have method getSelection().
In this FIDDLE, I have created a demo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'form',
renderTo: Ext.getBody(),
items: [{
xtype: 'multiselector',
title: 'Multi selector example',
fieldName: 'text',
viewConfig: {
deferEmptyText: false,
emptyText: 'No value selected'
},
search: {
field: 'text',
store: {
fields: [{
name: 'text',
type: 'string'
}],
data: [{
text: 'ABC'
}, {
text: 'ABC 1'
}, {
text: 'ABC 2 '
}, {
text: 'ABC 3'
}, {
text: 'ABC 4'
}]
}
}
}, {
xtype: 'button',
text: 'Get Value',
margin:15,
handler: function (btn) {
var multiselector = btn.up('form').down('multiselector');
if (multiselector.down('grid')) {
multiselector.down('grid').getSelection().forEach(rec => {
console.log(rec.get('text'));
});
}
}
}]
});
}
});

AngularJS nested ng-repeat access $parent array element

Right so I have a dilemma, that seems like a simple question but I can't figure it out.
I have a nested array:
$scope.rootItem = {
id: '1',
type: 'course',
title: 'Adobe Photoshop CC for beginners',
items: [{
id: '2',
type: 'label',
title:'Label Title',
items:[{
id: '3',
type: 'module',
title:'Module title',
items: [{
id: '4',
type: 'topic',
title:'Topic title',
items: [{
id: '5',
type: 'content',
title:'Content title'
}, {
id: '6',
type: 'content',
title:'Content title'
}]
}]
},{
id: '7',
type: 'resources',
title:'Resources'
},{
id: '8',
type: 'module',
title:'Module title',
items: [{
id: '9',
type: 'topic',
title:'Topic',
items: [{
id: '10',
type: 'question',
title:'Question title'
}]
}, {
id: '11',
type: 'topic',
title:'Topic title',
items: [{
id: '12',
type: 'content',
title:'Content title'
}]
}]
}]
},{
id: '14',
type: 'assessmentLabel',
title: 'Assessment Label',
items: [{
id: '15',
type: 'assessment',
title: 'Assessment Title',
items: [{
id: '16',
type: 'courseAssessment',
title: 'Course Assessment Question',
items: []
}]
}]
}]
};
That is outputted using ng-repeat. All works great there, by the way it is also sortable using ng-sortable (based on JQuery UI Sortable).
What I'm trying to do is duplicate lets say id: 5 using angular.copy().
HTML:
<a href="" title="Duplicate Content" data-ng-click="duplicate(ngModelItem, $parent.ngModelItem.items)">
<span class="icon-duplicate"></span>
</a>
That seems to work fine too. I'm able to pass the object to the function.
The problem arises when I try and push that object to its parents array. I read about $parent and what I think would make sense is passing $parent.ngModelItems.items to the ng-click as such:
data-ng-click="duplicate(ngModelItem, $parent.ngModelItem.items)"
Which to me makes sense, pass parents ngModelItem.items (items is array that ID:5 is part of). But I can't figure out why do I get $parent.ngModelItem.items as undefined.
This is my controller:
$scope.duplicate = function(item, parent) {
var itemCopy = angular.copy(item);
parent.push(item);
};
HTML ng-repeat:
<ul class="apps-container" ui-sortable="sortableOptions" ng-model="ngModelItem.items" ng-class="ngModelItem.type">
<li class="innerCont" ng-repeat="innerItem in ngModelItem.items">
<tg-dynamic-directive ng-model="innerItem" tg-dynamic-directive-view="getView">
</tg-dynamic-directive>
</li>
</ul>
But angular seems to have different ideas. So I guess my question is how can I pass parents ngModelItem.items (rootItem.items) so that I can access that array?
Can someone please explain why {{$parent.$parent.ngModelItems.id}} returns correct parent id. Yet when I try to pass that parent to the function such as
data-ng-click="duplicate(parent.parent.ngModelItem.items)"
It doesnt work
Directive below:
angular.module('tg.dynamicDirective', [])
.directive('tgDynamicDirective', ['$compile',
function($compile) {
'use strict';
function templateUrlProvider(getView, ngModelItem) {
if (getView) {
if (typeof getView === 'function') {
var templateUrl = getView(ngModelItem) || '';
if (templateUrl) {
return templateUrl;
}
} else if (typeof getView === 'string' && getView.length) {
return getView;
}
}
return '';
}
return {
restrict: 'E',
require: '^ngModel',
scope: true,
template: '<div ng-include="templateUrl"></div>',
link: function(scope, element, attrs, ngModel) {
scope.$watch(function() {
var ngModelItem = scope.$eval(attrs.ngModel);
var getView = scope.$eval(attrs.tgDynamicDirectiveView);
scope.ngModelItem = ngModelItem;
return templateUrlProvider(getView, ngModelItem);
}, function(newValue, oldValue) {
scope.templateUrl = newValue;
});
}
};
}
]);
After few hours of trying to fix this, and reading numerous articles about $scope inheritance I found out that ng-if create new scope using prototypical inheritance. Which I was not accounting for.
Which required me to insert one more $parent when passing it to the function as such:
data-ng-click="duplicate(ngModelItem, $parent.$parent.$parent.ngModelItem)"
and then in the controller do something like this:
$scope.duplicate = function(item, parent) {
var itemCopy = angular.copy(item);
var parentArray = parent.items;
parentArray.push(itemCopy)
};
Hope this will save someone hours of work, whoever runs into this problem.

Extjs listener out of the config

Hi extjs experts i have a simple question, but cant find the correct way to do it and was googling in for few days now. I have a listener inside config of extjs elements, it is easy to do it in this way, but how i could take the listener out of the config, and put it outside the config so config will be as minimum as possible and one listener can be used for many times just true the function call,
here is my code:
Ext.define("my.filter.TimeFilter",{
extend: "Ext.tab.Panel",
alias: "widget.myTimeFilter",
requires: ["my.filter.Filters"],
config: {
cls: 'ruban-filter-timefilter',
items: [
{
title: 'Time sections',
xtype: 'radiogroup',
fieldLabel: 'Time Selector',
items: [
{
boxLabel: '60 Mins',
name: 'unixMills',
inputValue: '3600000'
}, {
boxLabel: '8 Hours',
name: 'unixMills',
inputValue: '28800000'
}, {
boxLabel: '24 Hours',
name: 'unixMills',
inputValue: '86400000'
}, {
boxLabel: '7 Days',
name: 'unixMills',
inputValue: '604800000'
}, {
boxLabel: '30 Days',
name: 'unixMills',
inputValue: '2592000000'
}
],
listeners: {
change: function (field, newValue, oldValue) {
var endTime = new Date().getTime();
var startTime = endTime - newValue['unixMills'];
console.log("StartTime: " + startTime);
console.log("EndTime: " + endTime);
}
}
]
},
constructor: function(config){
this.callParent(arguments);
}
});
so i believe it should go after constructor as separate function or as listener itself, but i dont know, not so well familiar with js and extjs,
thanks everyone
You can add a listener outside of the config this way:
myElement.on('change', function () { ... }
There are quite a lot of possibilities.
If you have a lot of logic based on events, you can always create a controller and have them listen to the components. The controller documentation here should give you a pretty good idea of how to tie it together: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.app.Controller

Why is the list showing no elements in sencha touch 2?

I am very much beginner to Sencha Touch. I want to display a static list to the screen. The code I tried is from sencha docs guides 'using list'. However, blank screen appears when compiled and run. Do I have to add the list to the Viewport? What am I missing? Please help.
My code is:
Ext.application({
launch: function () {
Ext.create('Ext.List', {
store: {
fields: ['name'],
data: [
{ name: 'A' },
{ name: 'B' },
{ name: 'C' },
{ name: 'D' }
]
},
itemTpl: '{name}'
});
}
});
May be this one help you
Ext.create('Ext.List', {
fullscreen: true,
itemTpl: '{title}',
data: [
{ title: 'Item 1' },
{ title: 'Item 2' },
{ title: 'Item 3' },
{ title: 'Item 4' }
]
});
Sorry! My bad. I made it with a little bit of work.
I just did this:
launch: function() {
var list = Ext.Create('Ext.List',{..
.....
.....
itemTpl = '{name}'
});
Ext.Viewport.add(list);
}

Handlebars EACH iterator error

I'm new to Handlebars and while I found a workaround, I'm wondering why one registered helper works and one doesn't. The example that doesn't work is an example from the HB docs.
HTML:
<ul class="global-nav clearfix">
{{#each data}}
<li>{{text}}</li>
{{/each}}
</ul>
...
<ul class="content-nav clearfix">
{{#each data}}
<li>{{text}}</li>
{{/each}}
</ul>
Data:
var nav = [
{
name: 'global',
selector: $('.global-nav'),
data: [
{
text: 'Page 1',
href: 'page1.html'
}, {
text: 'Page 2',
href: 'page2.html'
}
],
name: 'content',
selector: $('.content-nav'),
data: [
{
text: 'Section 1',
href: '#section1'
}, {
text: 'Section 2',
href: '#section2'
}
]
}
];
Compiler:
$.each(nav, function() {
var obj = this,
src = obj.selector.html(),
template = Handlebars.compile(src),
html = template(obj.data);
obj.selector.html(html);
});
HB Helper (does not work - context is undefined):
Handlebars.registerHelper('each', function(context, options) {
var ret = "";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + options.fn(context[i]);
}
return ret;
});
HB Helper (does work using this instead of context):
Handlebars.registerHelper('each', function(context, options) {
var ret = "";
for(var i=0, j=this.length; i<j; i++) {
ret = ret + options.fn(this[i]);
}
return ret;
});
Any helps is appreciated.
Before looking at the rest of the JS, can I point out that the JSON looks wrong.
Name, selector and data are overwritten the second time they occur in your JSON. If this is just because of some bits being omitted when pasting to SO, then do ignore me ;o)
But if that is the real JSON, then it needs changing before looking at any functional stuff
<script>
var nav = [
{
name: 'global',
selector: $('.global-nav'),
data: [
{
text: 'Page 1',
href: 'page1.html'
}, {
text: 'Page 2',
href: 'page2.html'
}
]
}, // this line
{ // and this line added
name: 'content',
selector: $('.content-nav'),
data: [
{
text: 'Section 1',
href: '#section1'
}, {
text: 'Section 2',
href: '#section2'
}
]
}
];
</script>

Categories