I am trying to use the FuelEx tree control. I do not want to load each node on the tree when the user selects the node. I would rather load the entire tree structure at the point the pages loads. I have a controller already built that builds the correct json for my entire tree.
Is there an example of how to preload the entire structure?
I am currently attempting to use the following as a starting point. I will convert it a Datasource object once I get it working correctly.
$('#myTree').tree({
dataSource: function(options, callback){
var self = this;
var param = null;
if ("type" in options && options.type == "folder") {
if ("dataAttributes" in options && "children" in options.dataAttributes) {
param = options.dataAttributes["id"];
}
}
debugger;
if (param != null) {
$.ajax({
url: "/bundle-picker-data",
//data: 'id=' + param,
type: 'GET',
dataType: 'json',
success: function (response) {
if (response.status == "OK")
callback({ data: response.data })
},
error: function (response) {
console.log(response);
}
})
}
setTimeout(function () {
callback({ data: [
{ name: 'Ascending and Descending', type: 'folder', dataAttributes: { id: 'folder1' } },
{ name: 'Sky and Water I (with custom icon)', type: 'item', dataAttributes: { id: 'item1', 'data-icon': 'glyphicon glyphicon-file' } },
{ name: 'Drawing Hands', type: 'folder', dataAttributes: { id: 'folder2' } },
{ name: 'Waterfall', type: 'item', dataAttributes: { id: 'item2' } },
{ name: 'Belvedere', type: 'folder', dataAttributes: { id: 'folder3' } },
{ name: 'Relativity (with custom icon)', type: 'item', dataAttributes: { id: 'item3', 'data-icon': 'glyphicon glyphicon-picture' } },
{ name: 'House of Stairs', type: 'folder', dataAttributes: { id: 'folder4' } },
{ name: 'Convex and Concave', type: 'item', dataAttributes: { id: 'item4' } }
]});
}, 400);
},
multiSelect: true,
cacheItems: true,
folderSelect: false,
});
$('#tree-selected-items').on('click', function () {
console.log("selected items: ", $('#MyTree').tree('selectedItems'));
});
$('#myTree').on('loaded', function (evt, data) {
console.log('tree content loaded');
});
$('#myTree').on('opened', function (evt, data) {
console.log('sub-folder opened: ', data);
});
$('#myTree').on('closed', function (evt, data) {
console.log('sub-folder closed: ', data);
});
$('#myTree').on('selected', function (evt, data) {
console.log('item selected: ', data);
});
Thanks,
Greg
You do not have to use the dataSource function to call an external API each time. You can call the external API the first time dataSource is run and return the top level folders in the callback's data object. Then, the next time, do not make the ajax request and index into the collection of all items object based on the folder opened.
If that was unclear, load the object with all the tree information once at the beginning and grab whatever children you need out of it when a folder is opened based on that folder's attributes.
You have to load items each time--there is no other way with this control, but the items can be cached in memory and do not require an external network request.
Related
I'm migrating a small app from Extjs4 to 6.5. The problem is the treestore, which is very simple, but I cannot find out why the server routine is not called and also the exception-events are not called. I must overlook something, but I cannot find it.
The tree store is:
Ext.create("Ext.data.TreeStore", {
fields: ['mnu_Name'],
proxy: {
type: 'ajax',
headers: { "Content-Type": 'application/json' },
api: { read: '/Secure/WebServices/PageLayout.asmx/LoadMenuII' },
reader: {
type: 'json',
root: function (o) {
if (o.d) {
return o.d.data;
} else {
return o.children;
}
}
},
listeners: {
exception: function () {
alert('exception');
}
}
},
listeners: {
exception: function () {
alert('exception');
}
}
});
When I call the server routine with a plain Ajax call is works fine.
Ext.Ajax.request({
async: true,
url: '/Secure/WebServices/PageLayout.asmx/LoadMenuII',
headers: { 'Content-Type': 'application/json' },
success: function (response, options) {
//Extract data from the response
var data = Ext.decode(response && response.responseText || null, true);
//check op success=false
if (!data || data.success !== true) {
var errNumber = data && data.errNumber || 'Unknown',
errDescription = data && data.errDescription || 'Unknown';
Ext.Msg.alert("Warning", Ext.String.format(thisComp.errFormat, 'Warning in loading the menu definitione.', errNumber, errDescription), null, this, 9000)
return;
}
}
});
Any suggestion what I missed?
Thanks.
Arno
I'm trying to implement an autocomplete feature using Elasticsearch, angularJS and bootstrap.
I've got inspired by this solution :
autocomplete/typeahead angularjs bootstrap on elasticsearch
This is my Angular code:
angular.module('cineAngularApp')
.service('client', function (esFactory) {
return esFactory({
host: 'localhost:9200',
apiVersion: '2.2',
log: 'trace'
});
});
angular.module('cineAngularApp')
.controller('AutocompleteCtrl', function ($scope,client) {
$scope.getResult = function(val){
return client.search({
index: 'autocomplete_test',
fields: 'city',
q: 'city:'+val
}).then(function (resp) {
var keywords = [];
for(var i in resp.hits.hits){
var fields = (resp.hits.hits[i]).fields["city"];
keywords.push(fields);
}
return keywords;
}, function (err) {
console.trace(err.message);
});
};
});
Here is my problem
The above code works fine when I use a simple query, but as soon as I change the query by adding body it doesn't work.
angular.module('cineAngularApp')
.controller('AutocompleteCtrl', function ($scope,client) {
$scope.getResult = function(val){
return client.search({
index: 'autocomplete_test',
fields: 'city',
body: {
query: {
match: {
city: val
}
}
}
}).then(function (resp) {
var keywords = [];
for(var i in resp.hits.hits){
var fields = (resp.hits.hits[i]).fields["city"];
keywords.push(fields);
}
return keywords;
}, function (err) {
console.trace(err.message);
});
};
});
I don't know if it can help but I've also noticed when debugging that it's not a POST request anymore but it's an OPTION one.
Thanks in advance for your help.
Try with this:
return client.search({
index: 'movies',
"fields": [ "title" ],
"body": { // Use body field on elasticsearch client library
"query": {
"query_string": {
"fields": ["title"],
"query": "title:"+val
}
}
}
}).then(function (resp) {
// ....
})
I have an ng-grid that is connected to a SharePoint list. The SharePoint list is returning an ID number instead of the user name when I am trying to populate a field with a user name.
I have a function that is converting the ID to a user name.
$scope.getUserName = function (user) {
var userId = user;
$Service.getUserById($scope, userId).done(function (data) {
$scope.userName = data.d.Title;
})
}
When I am trying to call the function in a "cellTemplate", I can't send the ID variable to the function.
$scope.gridOptions = {
loading: true,
enableSorting: true,
enableFullRowSelection: true,
enableRowHeaderSelection: false,
showGroupPanel: true,
columnDefs: [
{ name: "Admin", field: "AdministratorId" },
{ name: "User", field: "ApprovedById" },
{ name: "SuperUser", cellTemplate: '<div>{{grid.appScope.getUserName(<pass the id variable here>)}}{{grid.appScope.userName}}</div>' }
],
data: 'gridData'
};
How do I get the userID from 'gridData' and send it to my function?
Update: The REST call I am using.
function getListItem(listName) {
var deferred = $.Deferred();
// query the list in the host web
var url = SPAppWebUrl + "/_api/SP.AppContextSite(#target)" +
"/web/lists/getbytitle('" + listName + "')/items?" +
"#target='" + SPHostUrl + "'";
$.ajax({
url: url,
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }, // return data format
success: onGetEntriesSuccess,
error: onoDataCallFailure
});
function onGetEntriesSuccess(data) {
deferred.resolve(data.d);
}
function onoDataCallFailure(data, errorcode, errorMessage) {
deferred.reject("Error: " + errorMessage);
}
return deferred;}
Your Code:
cellTemplate:
'<div>{{grid.appScope.getUserName(**<pass the id variable here>**)}}{{grid.appScope.userName}}</div>'
Pass id like this : row.entity.Id // this id is available in your raw data.
and now code is:
cellTemplate: '<div>{{grid.appScope.getUserName(row.entity.Id)}}{{grid.appScope.userName}}</div>'
I tried to create an item on the API and return a value with new 'ScheduleID', When I did a trace, API does return a new ScheduleID in the newly created object, but ScheduleID is never saved in the dataSource. Anyone know why?
vm.schedulerOptions = {
date: new Date(classStartDate.getUTCFullYear(), classStartDate.getUTCMonth(), classStartDate.getUTCDate(), 0, 0, 0),
height: 600,
views: [
"day",
{type: "week", selected: true},
],
dataSource: {
transport: {
read: function (options) {
if ($stateParams.classId) {
scheduleDf.getScheduleByClassId($stateParams.classId).success(function (result) {
options.success(result);
}).error(function (err) {
options.error(err);
})
} else if ($stateParams.sectionId) {
scheduleDf.getScheduleBySectionId($stateParams.sectionId).success(function (result) {
options.success(result);
}).error(function (err) {
options.error(err);
})
}
},
create: function (options) {
options.data.ClassId = classInfor.data[0].ClassID;
options.data.AtLocationId = vm.locationCb.dataItem().LocationID;
options.data.ConfirmationNumber = vm.ConfirmationNumber;
scheduleDf.createSchedule(options.data).success(function (result) {
//vm.grid.dataSource.read();
options.success(result);
}).error(function (err) {
options.error(err);
})
},
update: function (options) {
if (!fromMovingBar) {
options.data.AtLocationId = vm.locationCb.dataItem().LocationID;
fromMovingBar = false;
}
scheduleDf.updateSchedule(options.data).success(function (result) {
vm.grid.dataSource.read();
options.success(result);
}).error(function (err) {
options.error(err);
})
},
destroy: function (options) {
scheduleDf.deleteSchedule(options.data.ScheduleID).success(function (result) {
vm.grid.dataSource.read();
options.success();
}).error(function (err) {
options.error(err);
})
}
},
schema: {
model: {
id: "ScheduleID",
fields: {
start: {type: "date", from: "FromTime"},
end: {type: "date", from: "ToTime"}
}
}
}
},
editable: {
template: '<div ng-include="' + "'/schedule/_schedule_editor.html'" + '"></div>',
create: false
},
edit: function (e) {
e.container.data("kendoWindow").center();
e.container.find(".k-edit-form-container").width("auto");
e.container.data("kendoWindow").wrapper.css({width: 700});
},
moveEnd: function (e) {
fromMovingBar = true;
},
resizeEnd: function (e) {
fromMovingBar = true;
},
resources: [{
field: 'SessionTypeID',
dataColorField: 'ColorCode',
dataValueField: 'SessionTypeID',
dataTextField: 'SessionTypeName',
dataSource: sessionTypes.data
}]
};
The reason for current behavior is that the response from the server is not formatted the same way as the "read" request. You should try to insert the record inside array. For more info you can check this help article.
Also I notice that the Scheduler have no timezone option set. Please note that the timezone option is highly recommended to be set - for more details you can check the new Timezones help article.
how to add or save data that getting from ajax request to store or to model sencha touch 2
I have controller, store and a model. Ext.Ajax.request(); is called from controller and when it was successful I want move that data to store in json format
Ext.define('Myapp.controller.HomeController', {
extend: 'Ext.app.Controller',
config: {
control: {
"#homepage_id": {
show: 'onHomepage_idShow'
}
}
},
onHomepage_idShow: function (component, eOpts) {
var token = localStorage.getItem('Token'); //**************************************
console.log('test home', token);
var customHeaders = {
'Content-Type': 'application/json; charset=utf-8',
'ApiAuth': token
};
this.callAjax(customHeaders);
},
callAjax: function (headers) {
var customHeaders = headers;
Ext.Ajax.request({
url: 'http://localhost:9098/Folder/json/Get',
params: Ext.util.JSON.encode({
folderId: 0
}),
method: 'POST',
headers: customHeaders,
success: function (response) {
var decode_text = Ext.decode(response.responseText);
/*I want to add decode_text to a store from this contoller..*/
//var storez = Ext.data.StoreManager.lookup('commomStore_id');//****************
//this.getDataList().setStore(storez);
console.log(storez);
// process server response here
},
failure: function (response, opts) {
Ext.Msg.alert('Error', 'Error while submitting the form');
console.log(response.responseText);
},
scope: this
});
My Store:
Ext.define('Myapp.store.CommonStore', {
extend: 'Ext.data.Store',
requires: [
'Myapp.model.AuthTokenmodel'],
config: {
autoLoad: true,
model: 'Myapp.model.AuthTokenmodel',
storeId: 'commonStote_id',
proxy: {
type: 'localstorage',
id: 'commomStore_id',
reader: {
type: 'json'
}
},
fields: [{
name: 'authtoken'
}]
}
});
For that you have to parse your response and create Myapp.model.AuthTokenmodel objects out of it and then add those objects to your store using add method.
BTW if your response is in JSOn format you should parse it to JSON instead of text like this:
var respObj = Ext.JSON.decode(response.responseText);
console.log(respObj);
then create model objects using respObj data and add those to store:
var storez = Ext.data.StoreManager.lookup('commomStore_id');
storez.add(Ext.create('Myapp.model.AuthTokenmodel', {authtoken : respObj.authToken}));
Ext.getStore('commomStore_id').loadData(decode_text);