I know how to get a value from a selected row of a grid, just like this:
var records = Ext.getCmp('My_Grid').getSelectionModel().getSelection();
var record = records.length === 1 ? records[0] : null;
alert(record.get('name'));
But what I want is to get the name of all rows of the grid. To do it, I have used the method above, to write this functional function:
var MonTableau = new Array();
for (var j=0; j<=Ext.getCmp('My_Grid').getStore().getCount()-1; j++) {
Ext.getCmp('My_Grid').getView().select(j);
var records = Ext.getCmp('My_Grid').getSelectionModel().getSelection();
var record = records.length === 1 ? records[0] : null;
MonTableau[j+1]=record.get('name');
}
But it's not professional, I want more simple and professional method.
The ExtJS store provides an each function which applies a passed fn for each record cached (already loaded) in the store:
var myStore = Ext.getCmp('My_Grid').getStore();
myStore.each(function(rec) {
console.log(rec.get('name'));
});
P.S. I'm using console.log(); rather than alert(); as I think it's easier to read everything from the browser log.
Related
I create a grid and a toolbar with Two Menu of menuCheckItem. When i check the menuCheckItem the grid filters even with multiple values and multiple columns.
This working fine, as I have created grid 1st and then the toolbar
this.up('') // Used Instead of Ext.getCmp()
Working FIDDLE - https://fiddle.sencha.com/#view/editor&fiddle/2lop
Now I am trying to create same toolbar along with Menu separately on top 1st and then create grid at below. But while doing this, nly Multiple values is working.
I am trying to filter grid with multiple values as well as multiple columns.
Few things i tried -
// Only Filters One Value at a time with each Columns
store.queryBy(function(record,id){
return (record.get('name') == someValue && record.get('phone') == otherValue);
});
and
// Filters Many Columns with Single Value
filter.add(
property : name, phone
value : "somevalue"
operator : "OR"
);
Is there any way to implement Toolbar 1st and then grid ? And Filter grid with many values and columns simultaneously ?
In this FIDDLE i remade a function(checkchange), which is universal , can be put separately and you'll be able to attach it to every menucheckitem you create. The only thing is that if you add new menucheckitem filter you should name the menucheckitem id with the name of the columnDataIndex-Menu and add this columnDataIndex in menuFilters and thats all.
checkchange: function (checkbox, checked, eOpts) {
var menuFilters = ['name', 'phone'];
var getChecked = function (m) {
var checkedItems = [];
m.items.items.forEach(function (c) {
if (c.checked) {
checkedItems.push(c.text);
}
});
return checkedItems;
};
//
var menus = new Map();
menuFilters.forEach(function (e) {
menus.set(e, Ext.getCmp(e + '-Menu'));
});
//
var fieldValues = [];
menuFilters.forEach(function (e) {
fieldValues.push([e, getChecked(menus.get(e))]);
});
//
var store = checkbox.up('grid').store;
store.clearFilter();
//
if (fieldValues.length > 0) {
store.filterBy(function (record) {
var fV = this.fieldValues;
for (var i = 0; i < fV.length; i++) {
if (fV[i][1].length > 0) {
if (fV[i][1].indexOf(record.get(fV[i][0])) === -1) {
return false;
}
}
}
return true;
}, {
fieldValues: fieldValues
});
}
}
This problem has me stumped.
For some reason, the autoincrementing key generator in indexedDB resets after performing and update on an existing object with a put-transaction, leading to overwrites of data in the database.
For my app, I'm using a self written IndexedDB service for angularJS with all the basic CRUD functions implemented.
I may also add that I'm developing with Ionic Framework, even though I doubt that is to blame.
Considering the service is a work-in-progress, I've let the key path for an object store default to "id" with an autoincrementing strategy.
The indices for the given store, nevertheless, are up to the user to decide in a specific object.
As an example:
dbHelper.objectStores = [{'employees',
indices: [{indexName: 'name', isUnique: false},
{indexName: 'phone', isUnique: true}]}];
This would, unless already created in the db, create the object store 'employees' with indices 'name' and 'phone', where 'phone' would have to be a unique value while 'name' would not.
Here is the implementation of the openDB function.
Please note that dbHelper.objectStores is supposed to be empty as it's up to the user to assign these properties before opening the db(or else it is defaulted).
angular.module('dbProvider', [])
.factory('$db', ['$window', function($window) {
// DB Object
var dbHelper = {};
// Properties - Are given defaults unless assigned manually by user before openDB is invoked.
dbHelper.dbName = 'defaultDB';
dbHelper.dbVersion = 1;
dbHelper.objectStores = [];
dbHelper.openDB = function(onCompleteCallback, onErrorCallback) {
console.log('Atempting to open db with name ' + dbHelper.dbName + '.');
var request = $window.indexedDB.open(dbHelper.dbName, dbHelper.dbVersion);
// Invoked by indexedDB if version changes
request.onupgradeneeded = function(e) {
console.log('Version change. Current version: ' + dbHelper.dbVersion);
var db = e.target.result;
e.target.transaction.onerror = onErrorCallback;
if(dbHelper.objectStores.length === 0) {
dbHelper.objectStores.push({name:'defaultStore', indices: []});
}
for(var store in dbHelper.objectStores) {
if(db.objectStoreNames.contains(dbHelper.objectStores[store].name)) {
console.log(dbHelper.objectStores[store].name + ' deleted.');
db.deleteObjectStore(dbHelper.objectStores[store].name);
}
var newStore = db.createObjectStore(dbHelper.objectStores[store].name, {keyPath: "id", autoIncrement: true});
for(var index in dbHelper.objectStores[store].indices) {
newStore.createIndex(dbHelper.objectStores[store].indices[index].indexName,
dbHelper.objectStores[store].indices[index].indexName,
{unique : dbHelper.objectStores[store].indices[index].isUnique});
}
console.log(dbHelper.objectStores[store].name + ' created.');
}
};
request.onsuccess = function(e) {
console.log('DB ' + dbHelper.dbName + ' open.');
dbHelper.indexedDB.db = e.target.result;
onCompleteCallback();
};
request.onerror = onErrorCallback;
};
Here are some of the CRUD functions(the ones in question):
dbHelper.findItemWithIndex = function(keyValue, storename,
onCompleteCallback,onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var index = store.index(keyValue.key);
index.get(keyValue.value).onsuccess = function(event) {
onCompleteCallback(event.target.result);
};
};
dbHelper.addItemToStore = function(item, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.add(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.deleteItemFromStore = function(itemId, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.delete(itemId);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.updateItem = function(item, storename, onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.put(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
Finally, the code from the controller where the transactions are invoked.
The strategy here, is that the item is added to the db using the addItemToStore function the first time it is persisted, and then afterwards the updateItem function.
After adding the first time, the object is immediately fetched in order to keep working on it with the assigned id from the db.
$scope.updateTemplate = function() {
console.log('Saving..');
var onCompleteCallback = {};
if(!$scope.formTemplate.firstSave) {
onCompleteCallback = $scope.updateModel;
} else {
$scope.formTemplate.firstSave = false;
onCompleteCallback = $scope.setId;
}
$db.updateItem($scope.formTemplate, $scope.objectStore.name,
onCompleteCallback, $scope.dbError);
};
$scope.newItem = function() {
$db.addItemToStore($scope.formTemplate, $scope.objectStore.name,
$scope.setId, $scope.dbError);
};
$scope.setId = function() {
$db.findItemWithIndex(
{key: 'title',
value: $scope.formTemplate.title},
$scope.objectStore.name,
function(result) {
console.log(JSON.stringify(result));
$scope.formTemplate = result;
},
function(error) {
$scope.dbError(error);
});
}
It's here everything goes to hell.
I add an object, go back to another view and find it in the list with id=1.
I add another object, go back to the list view, and there it is with id=2.
And so forth and so forth..
Then, after updating either of the objects with the $scope.updateTemplate function, which also works like a charm, things get interesting:
The next object added gets id=1 and totally erases good old numero uno from earlier.
The next objects also get id's that cause them to replace the already existing objects.
What could cause this?
For testing I'm using Safari 8 in OS 10.10 and I'm deploying to an LGG2 with KitKat 4.4.2.
To be honest, I skimmed, but I saw this, "Safari 8" - the latest iOS and Safari have serious bugs with IndexedDB: http://www.raymondcamden.com/2014/9/25/IndexedDB-on-iOS-8--Broken-Bad
In iOS9, many of the IndexedDb bugs are fixed, but not all. We are currently testing on iOS9 Beta 2 and this particular bug that you found is not fixed.
We were able to work around this problem by not using autoincrement on our object stores. We just manually find the max key value and increment that.
Inserting an object looks something like this:
var store = db.transaction([entity], "readwrite").objectStore(entity);
store.openCursor(null, "prev").onsuccess = function (event) {
var maxKey = event.target.result.key || 0;
object.id = maxKey + 1;
store.add(object);
}
I have an extjs store associated with grid class. when I select a class, it gives ClassID of the record.
var ClassData = record.get('ClassID');
console.log(ClassData);
Based on this ClassID I am loading store of next grid:
var Grid = this.getSemGrid();
var Store = Grid.getStore(); // your grid's store
//load store with records having selected class ID
var g = Store.load( {params : {ClassID: ClassData }});
Till here everything is fine.
Once the store is loaded, I am getting all loaded records (Error Area)
var selected = g.getRange(); // getRange = select all records
Then pushing all the values of one field of all records in an array
var Excerpt = []; // start with empty array
Ext.each(selected, function(item) {
// add the fields that you want to include
var Obj = {
third_field: item.get('ExamName')
};
Excerpt.push(Obj); // push this to the array
}, this);
console.log(Excerpt);
Excerpt gives array of previously selected record not the current record.
I have also tried
Store.loadData([],false);
to clear all the loaded data of store before loading it again.
Got this working
var g = Store.load({
params : {ClassID: ClassData },
callback : function(records, operation, success){
var Excerpt = []; // start with empty array
Ext.each(records, function(item) {
// add the fields that you want to include
var Obj = {
third_field: item.get('ExamName')
};
Excerpt.push(Obj); // push this to the array
}, this);
}
});
I need to create an application in Google Script that can read values from a spreadsheet and load those values into text areas based on the value of the first column. For example, in the first column I have NickNames, on the second first name, on the third last name, on the fourth stop date. I have managed to load the nicknames into a listbox using getRange. But I need to know how to load the adjacent values (first, last, stop date) according to NickName into text areas. After the click of a button these values will be updated without creating a new record. Let me know. It would be of great help.
Here is the code I have so far. I need to load values into the corresponding text fields based on the nickname chosen from the dropdown box:
function doGet() {
var app = UiApp.createApplication();
var abspanel= app.createAbsolutePanel();
var stackpanel=app.createStackPanel();
var grid3=app.createGrid(12,12).setId('grd3');
var loadbtn= app.createButton('Load Employee Data');
var selectlbl=app.createLabel('Select Employee');
var active= SpreadsheetApp.openById('0Ai21cbl').getSheetByName('testing');
var endrow= active.getLastRow()-1;
var emplist=app.createListBox().setId('emps').setName('elist');
var emprange= active.getRange('A2:F100').getValues().sort();
for(var i=0; i<emprange.length; i++){
emplist.addItem(emprange[i][0])
}
var efirstlabel=app.createLabel('First').setId('elabel');
var efname=app.createTextArea().setId('efirst').setHeight('20px').setName('efst');
var elastlabel=app.createLabel('Last').setId('ellabel');
var elname=app.createTextArea().setId('elast').setHeight('20px').setName('elst');
var enicklabel=app.createLabel('NickName').setId('enlabel');
var enname= app.createTextArea().setId('enick').setHeight('20px').setName('enk');
var eattlabel= app.createLabel('Employee Attribute').setId('ealabel').setHeight('20px');
var eatt1='TLYDYE'
var eatt2='TLYDNE'
var eatt3='TLNDYE'
var eatt4='TLNDNE'
var eatt5='CAYDYE'
var eatt6='CAYDNE'
var eatt7='CANDYE'
var eatt8='CANDNE'
var eattlist=app.createListBox().setWidth('120px').setId('eattribute').setName('eattbt')
eattlist.addItem(eatt1);
eattlist.addItem(eatt2);
eattlist.addItem(eatt3);
eattlist.addItem(eatt4);
eattlist.addItem(eatt5);
eattlist.addItem(eatt6);
eattlist.addItem(eatt7);
eattlist.addItem(eatt8);
var estartlabel=app.createLabel('Start Date:');
var estartdate=app.createDateBox().setId('edate');
var estoplabel=app.createLabel('Stop Date:');
var estopdate=app.createDateBox().setId('sdate');
var inlabel=app.createLabel().setId('indexlabel');
//Edit Employee Handler
var loadhandler=app.createServerClickHandler('loadEmp');
loadhandler.addCallbackElement(stackpanel);
loadbtn.addClickHandler(loadhandler);
grid3
.setWidget(1,1,selectlbl)
.setWidget(1,2,emplist)
.setWidget(1,3,loadbtn)
.setWidget(2,1, efirstlabel)
.setWidget(2,2, efname)
.setWidget(2,3, elastlabel)
.setWidget(2,4, elname)
.setWidget(3,1, enicklabel)
.setWidget(3,2, enname)
.setWidget(4,1, eattlabel)
.setWidget(5,1,eattlist)
.setWidget(6,1,estartlabel)
.setWidget(7,1,estartdate)
.setWidget(8,1,estoplabel)
.setWidget(9,1,estopdate)
.setWidget(10,1,inlabel);
stackpanel.add(grid3, 'Edit Employee').setStyleAttribute("text-align", "center")
app.add(abspanel)
app.add(stackpanel)
return app;
}
function loadEmp(e){
var app=UiApp.getActiveApplication();
app.getElementById('efirst').setValue(e.parameter.elist);
return app;
}
Well, I guess it's easier if when adding each name to the list you add as the value to return the row number instead omitting and have just the name. This way it will be easier (i.e. you won't need to search for it) to reload the values on the loadEmp handler. e.g.
function doGet() {
//... the starting code your already have
var emprange = active.getDataRange().getValues(); //sorting a matrix doesn't make sense
//also, it's easier if you sort by the desired column the on the spreadsheet before hand
for( var i = 1; i < emprange.length; ++i )
emplist.addItem(emprange[i][0], i); //this 2nd parameter "i" is the return value
//... rest of your code
}
function loadEmp(e) {
var app = UiApp.getActiveApplication();
var active = SpreadsheetApp.openById('0Ai21cbl').getSheetByName('testing');
var index = +e.parameter.elist;
var empdata = active.getRange(index+1, 1, 1, 6).getValues()[0];
var cols = ['efirst','elast','enick']; //in the same order as in the spreadsheet
for( var i = 0; i < cols.length; ++i )
app.getElementById(cols[i]).setValue(empdata[i]);
return app;
}
It's the same thing for the save button, you'll just setValues instead of get.
I am fetching the data from the server each 10 sec, in this, i am getting 3 type of the data,
After the timeout call, i am removing the existing data, i can witness the console show that the array clears, but the elements still keep append upon.
how can i clear both elements in the DOM and unbind as well..
my close function is keep called, but the elements not remove from DOM.
my single view :
singleton.view = Backbone.View.extend({
tagName :'article',
template0 : function(value){
var label = value === 0 ? "projectName" : value === 1 ? "assignedTo" :"projectName";
return _.template("<a href='#'><%= "+label+" %></a>");
},
template1 : _.template($('#boardTemplate').html()),
initialize :function(prams){
this.template = this['template'+0](prams.subTempNo);
},
close:function(){
console.log('clean up') // i am getting consoled
this.unbind();// i am unbinding
this.remove();// i am removing
},
render:function(){
var temp = this.template;
this.$el.html(temp(this.model.toJSON()));
return this;
}
});
return singleton.view;
in the views :
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
listElement.close(); // whenever i call the new instance i am removing old stuff..
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
},
How can i fix this issue.. any correct approach pelase..
Ok just a quick rework.....you're going to have to test it out. Comment with what happens and I'll correct the code below.
Can you try
listViewSet:function(key,i){
var l = this.listCatch.length;
if(l > 0){
for (var i = 0; i < l; i++) {
console.log(this.listCatch[i]);
this.listCatch[i].remove();
}
}
this.listCatch = [];
_.each(this.listCollection.models, function(model){
that.listViewAppender(model,i); //setting agian.
});
},
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
console.log(listElement);
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
this.listCatch[i] = listElement;
},
I gone through across my functions, i find the issue in the line of this.listCatch[i] = listElement; wrongly declared.
Later i declared the array by manually, it's works fine. in my initialize i introduced 3 arrays, what i required now it works fine.
this.listCatch = [];
for(var i=0;i<this.listItems.length; i+=1){
this.listCatch[i] = [];
}
So before pushing the model to array, now the array introduced solved the issue.