Formly doesn't update field after set properties in controller - angularjs

I need dynamically load options of a field. Before the options loaded, if user click the select dropdown, they will see a empty list. To prevent that, I want to disable the select when page load, and then enable it after the options load.
The options loads fine, but the reset the disabled doesn't work
Code like
{
type: 'select', key: 'ref_code', defaultValue: '', templateOptions: {
'required': false, 'label': 'Supporter',
'placeholder': 'loading...', 'options': [], 'disabled': true
},
controller: function ($scope) {
$scope.to.loading = parentScope.ensure_option('resellers').then(function (items) {
$scope.to.options = options.get('resellers');
$scope.to.disabled = false;
return $scope.to.options;
});
}
},
Any idea?

You are loading it asynchronously but not waiting for the response to come back.
$scope.to.options = return options.get('resellers').then(function(response) {
$scope.to.disabled = false;
return response;
});

Related

AngularJS Include Refresh

I have a html page which I am including as follows.
<ng-include src="lowerTabURL"></ng-include>
This page contains a devextreme control which loads a datasource via ajax.
html:
<div class="tab-container" style="height:100%; width:100%">
<div dx-tabs="lowerTabOptions" dx-item-alias="lowerTab">
</div>
</div>
controller:
DemoApp.controller('NavigationController', function DemoController($scope, $templateCache) {
$scope.lowerTabURL = "LowerPanelTest";
$scope.currentSidebarId = 10100;
$scope.lowerTabOptions = {
dataSource: new DevExpress.data.CustomStore({
load: function (loadTabOptions) {
console.log('get tabs');
var d = $.Deferred();
$.ajax({
url: 'GetLowerTabs',
data: { currentSidebarId: $scope.currentSidebarId },
type: 'GET',
success: function (result) { console.log(result); d.resolve(result); }
});
return d.promise();
}
}),
animationEnabled: true,
swipeEnabled: true,
itemTitleTemplate: 'title',
height: '100%'
};
$scope.navBarClicked = function (sidebarId) {
console.log(sidebarId);
$scope.currentSidebarId = sidebarId;
}
});
This works correctly however I have a navbar which when clicked, should change the tab control.
Currently I am changing the sidebarId which gets passed to the ajax call but I need a way to reload the include page so that this is called again. I have tried changing the lowerTabUrl and then changing it back again but this doesnt refresh the page. What is the best way to do this?
It depends on your angular version, you will need to watch after changes of value for param sidebarId, # angular 1 this is achieved by scope.watch
scope.$watch('sidebarId', function(newValue, oldValue) {
// ..call refresh here
});
at angular 1.5 and later you can override ngOnChages
this.$onChanges = function (changesObj) {
if (changesObj.sidebarId) {
// changesObj.sidebarId.currentValue
}
};

Can't workout how to reload angular-datatable after deleting records from the database

I can't seem to work out how to redraw my Angular-Datatable after I delete a record from my database. I don't get any errors, but the table never seems to redraw unless I manually refresh the page. I have been trying to work with many examples from the website documentation.
I have my datatable:
$scope.dtInstance = {};
$scope.selectedItems = [];
$scope.toggleItem = toggleItem;
$scope.reloadData = reloadData;
// Build the User table
$scope.dtOptions = DTOptionsBuilder
.fromFnPromise(function() {
var deferred = $q.defer();
deferred.resolve(users);
return deferred.promise;
})
.withBootstrap() // Style with Bootstrap
.withOption('responsive', true)
.withDisplayLength(15) // Show 15 items initially
.withOption('order', [0, 'asc']) // Sort by the first column
.withOption('lengthMenu', [15, 50, 100]) // Set the length menu items
.withOption('createdRow', function(row, data, dataIndex) {
// Recompiling so we can bind Angular directive to the DT
$compile(angular.element(row).contents())($scope);
})
.withOption('headerCallback', function(header) {
if (!$scope.headerCompiled) {
// Use this headerCompiled field to only compile header once
$scope.headerCompiled = true;
$compile(angular.element(header).contents())($scope);
}
})
.withOption('fnRowCallback', formatCell);
$scope.dtColumns = [
DTColumnBuilder.newColumn(null).withTitle('Username').withClass('col-md-2').renderWith(createUsernameHyperlink),
DTColumnBuilder.newColumn('Email').withTitle('Email'),
DTColumnBuilder.newColumn('Level').withTitle('Role').withClass('col-md-2'),
DTColumnBuilder.newColumn('LastConnected').withTitle('Last Accessed'),
DTColumnBuilder.newColumn('Verified').withTitle('Account Verified').withClass('col-md-2'),
DTColumnBuilder.newColumn(null).withTitle('')
.notSortable()
.renderWith(function(data, type, full, meta) {
return '<input type="checkbox" ng-click="toggleItem(' + data.Id + ')" />';
}).withClass("text-center")
];
// Reload the datatable
function reloadData() {
var resetPaging = false;
$scope.dtInstance.reloadData(callback, resetPaging);
};
function callback(json) {
console.log(json);
};
And then I have my delete function that sits in the same controller. Calling reloadData() on a successful response from the service. I can see from the console.log that it is calling the function correctly, but nothing happens.
$scope.deleteUser = function( selectedItems ) {
swal({
title: 'Are you sure?',
text: 'Are you sure you want to delete the selected account profile(s)? This process cannot be undone...',
type: 'warning',
showCancelButton: true,
confirmButtonText: 'Delete',
confirmButtonColor: "#DD6B55",
closeOnConfirm: false,
allowEscapeKey: true,
showLoaderOnConfirm: true
}, function() {
setTimeout( function() {
// Delete user
UsersService.deleteUser( selectedItems.toString() )
.then(function( data ) {
// Show a success modal
swal({
title: 'Success',
text: 'User has been deleted!',
type: 'success',
confirmButtonText: 'Close',
allowEscapeKey: false
}, function() {
reloadData(); //<== Calls the function but doesn't do anything
//$state.go('users');
});
}, function() {
// Show an error modal
swal({
title: 'Oops',
text: 'Something went wrong!',
type: 'error',
confirmButtonText: 'Close',
allowEscapeKey: true
});
});
}, 1000);
});
};
Just wondering if I have missed some step?
As suggested by #davidkonrad in a previous comment and more so from the Angular-Datatable's author, I was not reloading my content when attempting to redraw my table. Even though I was referencing my data (users) from an injected service, it was never getting updated within the controller and so my table content was never differing.
The author suggested that it is preferable to load the data from a promise that makes a HTTP request, thus allowing further calls to the promise each time the table redraws.
So instead of this:
// Build the User table
$scope.dtOptions = DTOptionsBuilder
.fromFnPromise(function() {
var deferred = $q.defer();
deferred.resolve(users);
return deferred.promise;
})
.withBootstrap() // Style with Bootstrap
I changed it to this:
// Build the User table
$scope.dtOptions = DTOptionsBuilder
.fromFnPromise(function() {
return UsersService.getUsers();
})
.withBootstrap() // Style with Bootstrap
Which now updates my table fine upon each redraw event with a call to $scope.dtInstance.reloadData();
My Github post can be found here
setTimeout function works from outside of the angular digest cycle since it's async. If you want actions you take inside a timeout to apply to the angular digest cycle you should use $timeout instead.
Another option is to use $scope.apply(), but this will just mimic the $timeout function.
Please note that you'll need to inject $timeout to your controller.

Return a formatted array of events

I'm trying to integrate Angular Bootstrap Calendar to my Laravel 5 project. Right now, the calendar works using the provided pre-populated demo list of events.
vm.events = [
{
title: 'An event',
type: 'warning',
startsAt: moment().startOf('week').subtract(2, 'days').add(8, 'hours').toDate(),
endsAt: moment().startOf('week').add(1, 'week').add(9, 'hours').toDate(),
draggable: true,
resizable: true
}, {
title: 'Event 2',
type: 'info',
startsAt: moment().subtract(1, 'day').toDate(),
endsAt: moment().add(5, 'days').toDate(),
draggable: true,
resizable: true
}, {
title: 'This is a really long event title that occurs on every year',
type: 'important',
startsAt: moment().startOf('day').add(7, 'hours').toDate(),
endsAt: moment().startOf('day').add(19, 'hours').toDate(),
recursOn: 'year',
draggable: true,
resizable: true
}
];
I would like to retrieve and format the events from my database like the example above, but I'm not sure how to tackle this from my controller.
On the Angular Calendar side, I've read that I can use the angular $http service to load the events, like this:
$http.get('/events').success(function(events) {
//TODO - format your array of events to match the format described in the docs
$scope.events = events; //Once formatted correctly add them to the scope variable and the calendar will update
});
Any help would be greatly appreciated
What you would want to do is create a service that takes care of all the HTTP request/response handling and have your controller consume it to get/save/update data. Something like:
// assuming that you have a REST service endpoint at /events
// create your service that will handle all HTTP interaction for the events resource
app.factory('EventsService', ['$http', function($http) {
return {
getAll: function() {
// fetch all events asynchronously
return $http.get('/events').success(function(response) {
var events = response.data;
// if you need to do any pre-processing of the events first, do it here
// pass your events to the next function in the promise chain.
return events;
}, function(err) {
// handle errors here
// pass your error object down the chain in case other error callbacks are added later on to the promise.
return err;
});
}
};
}]);
app.controller('YourController', ['$scope', 'EventsService', function($scope, EventsService) {
// call the asynchronous service method and add your promise success callback that returns your array of events to be bound to your context.
EventsService.getAll().then(function(evts) {
$scope.events = evts;
}, function(err) {
// do any additional error handling here
});
});

Sencha Touch Load Mask

I have list and pull down to refresh plugin in it. When the refresh function fires i would like to show the load mask. But its not showing there. when i commented store.removeAll(); line i can see the loadmask working. I dont konw whats the problem with store.removeAll(). Please help me to solve this issue. Thanks in advance
{
xclass: 'Ext.ux.PullRefreshFn',
pullRefreshText: 'Pull down for refresh Contacts!',
refreshFn: function() {
console.log('pull refresh working');
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Please Wait...'
});
var store = Ext.getStore('Contactsstore');
store.removeAll();
var url = apiurl+'Contact.ashx?switch=GetContactList&api_id=4&getDataAgain=true';
store.getProxy().setUrl(url);
store.loadPage(1,{
callback: function (records, operation, success, response) {
if (success==1) {
Ext.Viewport.setMasked(false);
} else {
Ext.Viewport.setMasked(false);
}
}
});
Ext.getCmp('searchcontact').reset();
}
}
Here is my Store configuration
Ext.define('WinReo.store.Contactsstore', {
extend: 'Ext.data.TreeStore',
requires: [
'WinReo.model.Contactsmodel'
],
config: {
storeId: 'Contactsstore',
defaultRootProperty: 'items',
model: 'WinReo.model.Contactsmodel',
autoLoad: false,
pageSize: 20,
proxy: {
type: 'ajax',
method:'post',
id: 'Contactsstoreproxy',
url:apiurl+'Contact.ashx?switch=GetContactList&api_id=4&getDataAgain=false',
reader: {
type: 'json',
rootProperty: 'items'
}
},
listeners: {
load: function(store, records, successful, operation, eOpts) {
callback:{
succes:
if(store.getCount()!=0){
var RecordCount=store.getAt(0).get('RecordCount');
//console.log('RecordCount',RecordCount);
store.setTotalCount(RecordCount);
var storectscount = store.getTotalCount();
//Ext.Msg.alert('Store Total count',storectscount, Ext.emptyFn);
}
}
}
}
}
}
});
Loading masks won't get rendered until the browser has a chance to render them, and that won't happen until your Javascript code completes. I suspect that for some reason, the removeAll call isn't completing quickly (or at all), or an event listener on clear isn't completing like it needs to. Check your store's configuration for syncRemovedRecords: true and autoSync: true. You can also try removeAll(true) to keep the clear event from firing.
Update
Looking at your store definition, I can see at least one problem: Your load listener doesn't look like it's defined properly. You're defining a callback field inside of a function (which isn't going to compile), and 'succes' is misspelled. Is this what you had in mind?
load: function(store, records, successful, operation, eOpts) {
if(successful === true && store.getCount()!=0){
var RecordCount=store.getAt(0).get('RecordCount');
store.setTotalCount(RecordCount);
}
}
}

How to reload carouse items onPainted? Sencha touch

I would like to reload items in the carousel onPainted() method. So whenever users come the carousel item then we have a fresh list of carousel items. Problem at this point of time (please have a look at the source code), the carousel reloads items, however until I touch the carousel, the first carousel item is blank (or not selected) and no items selected. I would like at least to see the first element to be selected.
So here is the simplified source code:
Ext.define("APN.view.FeaturedCarousel", {
config: {
listeners: {
painted: function(carousel, eOpts) {
var features_url = Ext.getStore("regionalisation").getRegionalisedMenus().feature.url;
this.setCarouselStore(features_url);
}
}
},
initialize: function () {
this.callParent();
var me = this;
var features_url = Ext.getStore("regionalisation").getRegionalisedMenus().feature.url;
this.setCarouselStore(features_url);
},
setCarouselStore: function (features_url) {
var me = this;
Ext.Ajax.request({
url: features_url,
success: function (response) {
me.removeAll();
if (!xml) return;
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
fields: [
],
data: xml,
proxy: {
type: 'memory',
reader: {
type: 'xml',
rootProperty: 'xml',
record: 'item'
}
}
});
store.each(function (record) {
var item = Ext.create("Ext.Container", {
html: "some HTML HERE"
});
me.add(item);
});
}
});
}
});
I think you should activate the first item in the carousel once all the items are added. Like this:
store.each(function (record) {
var item = Ext.create("Ext.Container", {
html: "some HTML HERE"
});
me.add(item);
});
me.setActiveItem(0);
This should make the first item selected.
If you want to change the carousel content every time it is activated, use "active" listener. Because "painted" will be called only once and if you want that, then no point in adding a painted event because you are already calling the "setCarouselStore" function in "initialize" method.

Resources