ExtJS ComboBox dynamic JSON updates - json

I have found numerous issues explaining why the JSON store is not updated in an Ext JS comboBox.
We have made a re-usable ExtJS combobox control, this is the source code for it.
Ext.define('ReusableComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.Reusablecombobox',
queryMode: 'local',
forceSelection: true,
valueField: 'id',
displayField: 'displayField',
autoLoad: false,
initComponent: function () {
if (!this.store) {
var store = Ext.create('Ext.data.Store', {
autoLoad: this.autoLoad,
fields:['id', 'displayField', 'Id', 'Code', 'Description', 'IsIncluded', 'IsActive'],
proxy: {
type: 'ajax',
url: urlContent('validurl/getcodes'),
reader: {
type: 'json',
root: 'data'
}
}
});
store.on('load', this.handler_StoreLoad, this);
Ext.apply(this, {
store: store
});
}
this.callParent();
},
handler_StoreLoad: function (store, records, successful, options) {
addFieldsToList(records, function (item) {
item.data['id'] = item.data.Id;
item.data['displayField'] = item.data.Code + ' | ' + item.data.Description;
});
},
addFieldsToList: function( list, buildDisplayFieldFunc ){
if( list ){
for( var i=0, j=list.length; i<j; i++ ){
buildDisplayFieldFunc( list[i] );
}
return list;
}
}
});
When I dynamically add another item to the comboBox store, the comboBox does not refresh. I have tried the following things.
The following tries comes up with blank elements in the comboBox
Call the removeAll(), clearValue() functions on the store and re-initialize using the bindStore(model), it comes up with empty list items.
comboBox.store.reload(model);
The following tries adds the new item as a blank element in the comboBox
var data = [];
data.push(new Ext.data.Record({id: options[0].Id, displayField : options[0].Code + ' | ' + options[0].Description}));
comboBox.store.add(data);
comboBox.store.loadData(data, true);
Has anyone seen and struggled with what I am talking about ?
Thanks in advance for your help.

I tried your code and it works with the below change and it is not required to call store.loadData
var data = []; data.push({id: options[0].Id, displayField : options[0].Code + ' | ' + options[0].Description});
comboBox.store.add(data);
What you have done is not the best way to map the returned JSON to your store,
I have modified your code for the mappings which is the best way to do and it doesn't require you to call the load listener and manually add the records.
Ext.define('ReusableComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.reusablecombobox',
queryMode: 'local',
forceSelection: true,
valueField: 'id',
displayField: 'displayField',
autoLoad: false,
initComponent: function () {
if (!this.store) {
var store = Ext.create('Ext.data.Store', {
autoLoad: this.autoLoad,
fields:[ 'Id', 'Code', 'Description', 'IsIncluded', 'IsActive',
{
name: 'displayField',
convert: function(v, record) {
return record.get('Code') + ' | ' + record.get('Description');
}
},
{name: 'id', mapping: 'Id'}
],
proxy: {
type: 'ajax',
url: urlContent('validurl/getcodes'),
reader: {
type: 'json',
root: 'data'
}
}
});
Ext.apply(this, {
store: store
});
}
this.callParent();
}});

Related

angularjs will not bind data to $scope after $http call and promise return

Having an issue with binding data to a var named $scopethings. I call mysql database and it sends data over through express.
app.get('/options', function(req, res)
{
var arr = [];
var query = "SELECT * FROM memberships";
con.query(query, function(err, result)
{
if (err)
{
console.log("error retriving memberships from the db " + err);
throw err;
}
res.send(result);
});
/* server side of things */
now to go to the angular side.
app.controller('MainController', ['$http', '$scope', '$log',
'getmemOptions', function($http, $log, $scope, getmemOptions)
{
var gymmem = this;
gymmem.onSubmit = onSubmit;
gymmem.options;
$scope.things;
var promise = $http.get('/options');
promise.then(function(payload)
{
$scope.things = angular.copy(payload.data);
alert(JSON.stringify($scope.things)); // 1st call view $scope.things
});
alert(JSON.stringify($scope.things)); // 2nd call view $scope.things
In my first call to JSON.stringify($scope.things) I can see that it pull the correct information from the database; however the second call yields undefined. I am aware of the asynchronous nature of javascript of how the $http call will return a promise. I believe I am handling the promise right, but if I am not please let me know how I can change things up. Thank you in advance!!
EDIT
Here is angular-formly template.
gymmem.model =
{
first_n: '',
last_n: '',
email: '',
age: '',
memberships: '',
};
gymmem.fields = [
{
key: 'first_n',
type: 'input',
model: gymmem.model.f_name,
templateOptions:
{
type: 'text',
label: 'First Name',
placeholder: 'Enter your first name',
required: true
}
},
{
key: 'last_n',
type: 'input',
// model: gymmem.model.l_name,
templateOptions:
{
type: 'text',
label: 'Last Name',
placeholder: 'Enter your last name',
required: true
}
},
{
key: 'email',
type: 'input',
//model: gymmem.model.email,
templateOptions:
{
type: 'text',
label: 'Email Address',
placeholder: 'Enter your email address',
required: true
},
hideExpression: '!model.first_n || !model.last_n'
},
{
key: 'age',
type: 'input',
//model: gymmem.model.age,
templateOptions:
{
type: 'number',
label: 'Age (must be 16+)',
placeholder: 'Enter your age',
required: true
},
//check if customer is 16+
validators:
{
ofAge: function($viewValue, $modelValue, scope)
{
var age = $viewValue || $modelValue;
if (age >= 16)
return true;
return false;
}
}
},
{
key: 'memberships',
type: 'select',
model: gymmem.model.membership,
templateOptions:
{
label: 'Membership Types',
required: true,
placeholder: "Select Membership",
options: $scope.things//[{"name":"Martial Arts Membership","value":45},{"name":"Regular Gym Membership","value":30},{"name":"Cardio Classes Membership","value":35}]
}
},
];
function onSubmit()
{
//alert(JSON.stringify(gymmem.model), null, 2);
$http.post('/', gymmem.model).success(function(req)
{
gymmem.model = {};
console.log("Front end data " +req);
}).error(function(err)
{
console.log(err);
});
};
}
]);
Here just in case is the html.
<body ng-app="GymApp" ng-controller="MainController as gymmem">
<div class="container col-md-4 col-md-offset-4">
<form ng-submit="gymmem.onSubmit()" novalidate>
<h1> Buy Gym Membership(s) </h1>
<formly-form model="gymmem.model" fields="gymmem.fields">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
</div>
</body>
[{"name":"Martial Arts Membership","value":45},{"name":"Regular Gym Membership","value":30},{"name":"Cardio Classes Membership","value":35}] is the data I want $scope.things to have. The data here is being processed through the $http.get() call.
Sorry for formatting issues. New to stackoverflow posting and somewhat in a hurry.
It looks to me that you're handling the $http call just fine if you're getting the results in your first alert().
The issue here seems to be within your controller declaration:
app.controller('MainController', ['$http', '$scope', '$log',
'getmemOptions', function($http, $log, $scope, getmemOptions)
You have mismatching dependency injections. Notice how $scope is your 2nd injection, but in your controller function you're referring to it as $log. So you're not actually binding anything to $scope here. You're really trying to bind it to $log.
Change the order of your dependencies in your controller declaration to this:
app.controller('MainController', ['$http', '$scope', '$log',
'getmemOptions', function($http, $scope, $log, getmemOptions)

ExtJs 5 -- Setting the proxy for a store

I have a Store where I am trying to define its proxy in the constructor, like so:
Ext.define('App.store.LabStore', {
extend: 'Ext.data.Store',
constructor: function(config) {
var prox = new Ext.data.proxy.Ajax();
prox.setUrl('http://server:port/app/labs');
prox.setHeaders({'Content-type': 'application/json'});
prox.setReader({type: 'json',rootProperty: 'departmentList'});
this.setProxy(prox);
this.callParent(arguments);
},
autoLoad: false,
model: 'App.model.Lab'
});
Unfortunately, this won't work. What does work, from my controller, is this:
var labStore = Ext.create("App.store.LabStore");
var url = 'http://server:port/app/labs';
labStore.getProxy().setUrl(url);
labStore.on('load','checkLabs',this);
labStore.load();
I realize that the latter method works and perhaps I should just move on but I do want to try to figure out why I cannot set the proxy in the constructor and/or what I'm doing wrong with that approach.
Thanks in advance!
Frank
There is no need to define proxy in constructor. You can define all your properties in config object like so:
//define model
Ext.define('App.model.Lab', {
extend: 'Ext.data.Model',
fields: [{
name: 'name',
type: 'string'
}, {
name: 'closed',
type: 'bool'
}]
});
//define store
Ext.define('App.store.LabStore', {
extend: 'Ext.data.Store',
model: 'App.model.Lab',
proxy: {
type: 'ajax',
url: 'labs.json',
reader: {
type: 'json',
rootProperty: 'departmentList'
}
},
autoLoad: false
});
//initialize store
var store = Ext.create('App.store.LabStore');
// load data from source
store.load();
Here is a fiddle
or you can pass the proxy config when creating store class, like so:
var store = Ext.create('App.store.LabStore', {
proxy: {
type: 'ajax',
url: 'labs.json',
reader: {
type: 'json',
rootProperty: 'departmentList'
}
}
});
but if you need to do it in a constructor you can:
//define store
Ext.define('App.store.LabStore', {
extend: 'Ext.data.Store',
constructor: function(config) {
config = Ext.applyIf({
proxy: {
type: 'ajax',
url: 'labs.json',
reader: {
type: 'json',
rootProperty: 'departmentList'
}
}
}, config);
this.callParent([config]);
},
autoLoad: false
});
Here is a fiddle
The config parameter is used to initialise the Store. It includes, by default, an undefined proxy. I'd be about 90% sure that it's reseting the proxy during the call to the parent constructor.
Try setting the proxy into the config object instead.
Ext.define('App.store.LabStore', {
extend: 'Ext.data.Store',
constructor: function(config) {
var prox = new Ext.data.proxy.Ajax();
prox.setUrl('http://server:port/app/labs');
prox.setHeaders({'Content-type': 'application/json'});
prox.setReader({type: 'json',rootProperty: 'departmentList'});
config.proxy = prox;
this.callParent(arguments);
},
autoLoad: false,
model: 'App.model.Lab'
});

Ajax read large json file slowly

I am using AJAX to read a large JSON file (about 15 MB minified), in order to display autocomplete suggestions on a text field.
The problem is that after user types 4 characters in order the suggestions to begin, i have to wait around 20 to 60 seconds which makes actually impossible to use it.
I don't know any techniques how i could make it read the JSON file faster.
I would like to read your suggestions...
My AJAX request is :
$(document).ready(function () {
$("#card").autocomplete({
source: function (request, response) {
$.ajax({
dataType: "json",
data: {
term: request.term,
},
type: 'GET',
contentType: 'application/json; charset=utf-8',
xhrFields: {
withCredentials: true
},
cache: true,
url: base_url+'/test123/wp-content/plugins/trading-collectible-cards/public/js/AllSets.json',
success: function (data) {
var keys = Object.getOwnPropertyNames (data)
var outputArray;
$.each(keys,function(ele, val){
var array = $.map(data[val].cards, function (set) {
return {
label: set.name + " (" +data[val].name + ")",
value: set.name,
text: set.text,
multi: set.multiverseid,
rarity: set.rarity,
setname:keys[ele],
setfull:data[val].name
}
});
if (ele == 0)
outputArray = $.merge([], array);
else {
outputArray = $.merge(outputArray, array);
}
});
response($.ui.autocomplete.filter(outputArray, request.term));
},
error: function (data) {
}
});
},
minLength: 3,
open: function () {
},
close: function () {
},
focus: function (event, ui) {
},
select: function (event, ui) {
$( "#card" ).val( ui.item.label );
$( "#description" ).html( ui.item.text );
}
});

AngularJS - Multiple StateParems

We are still picking up and learning AngularJS but can't seem to figure this issue out, we want to be able to select a product type and use the formData value ("productType":"1") image1 to display the correct JSON product data related to this ID image2.
These are our controllers below within app.js, we have tried using multiple $stateParems but cant get seem to get the producttype id working with the stateParems.
Each productType ID is related to its own JSONstub, this is what we are using currently but this only grabs the jobID and not the producttype id below.
$scope.productid = $stateParams.jobID[0];
url: 'http://jsonstub.com/producttype/' + $scope.productid,
Here is our Plnkr, to find the Product Type section Click 'Login' > 'CHD24 - 26384108' 'View' > Next.
If anyone could advice and point us in the right direction this would help massively, also as we are new to AngularJS if you see anything else that we are doing wrongly please point it out.
Thank you.
// Product Type
.controller('warrantyCtrl', function($scope, $http, $stateParams) {
$scope.params = $stateParams.jobID[0];
$scope.dataLoaded = false;
$http({
url: 'http://jsonstub.com/warranty/' + $scope.params,
method: 'GET',
dataType: 'json',
data: '',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://run.plnkr.co',
'JsonStub-User-Key': '1357f082-ea56-46f0-adc5-3e5c273f6f87',
'JsonStub-Project-Key': 'e4f971a2-db30-45a0-80f9-bfa41b922c64'
}
}).success(function(data, status, headers, config) {
$scope.warrantydata = data;
$scope.dataLoaded = true;
}).error(function(data, status, error, config) {
$scope.warrantydata = [{
heading: "Error",
description: "Could not load json data"
}];
$scope.dataLoaded = false;
});
$scope.formData = {
'jobID': $scope.params
};
// Product Type Select
$scope.products = [{
id: '1',
name: 'Petrol Lawnmower'
}, {
id: '2',
name: 'Electric Lawnmower'
}, {
id: '3',
name: 'Petrol Chainsaw'
}, {
id: '4',
name: 'Electric Chainsaw'
}, {
id: '5',
name: 'Petrol Timmer'
}, {
id: '6',
name: 'Electric Timmer'
}, {
id: '7',
name: 'Etc'
}];
})
// Product Data
.controller('warrantyFormProductType', function($scope, $http, $stateParams) {
$scope.productid = $stateParams.jobID[0];
$http({
url: 'http://jsonstub.com/producttype/' + $scope.productid, // This needs to be productType id
method: 'GET',
dataType: 'json',
data: '',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://run.plnkr.co',
'JsonStub-User-Key': '1357f082-ea56-46f0-adc5-3e5c273f6f87',
'JsonStub-Project-Key': 'e4f971a2-db30-45a0-80f9-bfa41b922c64'
}
}).success(function(data, status, headers, config) {
$scope.productdata = data;
}).error(function(data, status, error, config) {
$scope.productdata = [{
heading: "Error",
description: "Could not load json data"
}];
})
// Add / Remove Columns (Still working on)
$scope.removeRow = function(index) {
$scope.productdata.splice(index, 1);
if ($scope.productdata.length() === 0) {
$scope.productdata = [];
}
};
$scope.addRow = function() {
var newrow = [];
if ($scope.productdata.length === 0) {
newrow = [{
'en': ''
}];
} else {
$scope.productdata[0].forEach(function(row) {
newrow.push({
'en': ''
});
});
}
$scope.productdata.push(newrow);
};
});
Is your API request supposed to be like this http://jsonstub.com/2/1 ?
Assuming yes, I've updated the code here
But I am getting Error 400 for this request.
Take a look and comment if this is what you needed.

How do get jquery fullcalendar to pass additional parameters to my json feed script

My code is as follows
jQuery('#calendar').fullCalendar({
weekMode: 'liquid',
events: themeforce.events,
eventRender: function (event, element) {
element.find('span.fc-event-title').html(element.find('span.fc-event-title').text());
}
});
where themeforce.events is a variable containing an encoded url of the json feed a php file - all works well.
I tried replacing events: themeforce.events, with
events: {
url: themeforce.events,
type: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
However now the calendar fails to load.
What can I do?
I wanted the start and end times for a post ajax request and it took me a bit of time to work it out.
This might help you:
events: function(start, end, timezone, callback) {
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: {
start: start.format(),
end: end.format(),
custom_param1: 'value 1',
custom_param2: 'value 2',
},
error: function () {
alert('there was an error while fetching events!');
},
success: function(doc) {
var events = [];
$.each(doc,function (index, e) {
events.push(e);
});
callback(events);
}
});
}
You should use extraParams as explained in doc : https://fullcalendar.io/docs/events-json-feed
var calendar = new Calendar(calendarEl, {
eventSources: [
// your event source
{
url: '/myfeed.php',
method: 'POST',
extraParams: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
failure: function() {
alert('there was an error while fetching events!');
},
color: 'yellow', // a non-ajax option
textColor: 'black' // a non-ajax option
}
// any other sources...
]
});
Also be sure your feed's url return raw json data array !
Just put "data" instead of "extraParams" in "events"
events: {
url: 'service.php',
method: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
},
failure: function() {
alert('there was an error while fetching events!');
},
}