First code and Trigger is work
filterPanel.on("form:filter", function(data){
var criterion = data
filteredData.filter(criterion)
data1 = filteredData.filter(criterion)
if(data1.length === 0){
$('.warn').finish().slideDown(80,function(){
setTimeout(function(){$('.warn').finish().slideUp(80)},3000)
})
} else {
$('.statistic').fadeOut(100,function(){
chartPanel.trigger("chart:render") //This Works and call "chart:render"
$('.statistic').fadeIn(100)
})
}
})
But when I call in
filterPanel.trigger("form:filter" ,firstFilter)
In the same page above the first code isn't working? I want call the "form:filter"
Here's my full code
programming.module("Program.Chart",function(Chart, programming, Backbone, Marionette, $, _){
Chart.Controller = {
getData : function(){
var data1 = programming.request("data:entities");
if(data1 !== undefined){
var filteredData = programming.Program.FilteredCollection({
collection : data1,
filterFunction : function(criterion){
return function(data){
var dateModel = moment(data.get("tanggal"),'DD/MM/YYYY');
var startDate = moment(criterion.date1,'DD/MM/YYYY')
var endDate = moment(criterion.date2,'DD/MM/YYYY')
if(dateModel.isSameOrAfter(startDate)){
if(dateModel.isSameOrBefore(endDate)){
return data
}
}
}
}
})
filterPanel = new Chart.filterPanel()
chartLayout = new Chart.chartLayout()
emptyView = new Chart.emptyView();
var firstFilter = {
date1 : "10/08/2016",
date2 : "10/08/2016"
}
filterPanel.trigger("form:filter" ,firstFilter)
chartPanel = new Chart.chartPanel({
collection: filteredData
})
filterPanel.on("form:filter", function(data){
var criterion = data
filteredData.filter(criterion)
data1 = filteredData.filter(criterion)
if(data1.length === 0){
$('.warn').finish().slideDown(80,function(){
setTimeout(function(){$('.warn').finish().slideUp(80)},3000)
})
} else {
$('.statistic').fadeOut(100,function(){
chartPanel.trigger("chart:render")
$('.statistic').fadeIn(100)
})
}
})
filterPanel.on("filter:render", function(){
//DatePicker
var format = "DD/MM/YYYY"
var date1 = new Pikaday({
field : $("#date1",this.el)[0],
format : format
})
$("#date1",this.el)[0].value = moment().add('days').format(format)
var date2 = new Pikaday({
field : $("#date2",this.el)[0],
format : format
})
$("#date2",this.el)[0].value = moment().add('days').format(format)
var selectdate = $('#publicdate',this.el)[0];
selectdate.addEventListener("change",function(){
var value = selectdate.value;
var date1 = $('#date1',this.el)[0];
var date2 = $('#date2',this.el)[0];
if(value==="today"){
date1.value = moment().add('days').format(format)
date2.value = moment().add('days').format(format)
$(date1).attr('disabled',true);
$(date2).attr('disabled',true);
} else if(value==="yesterday"){
date1.value = moment().add(-1,'days').format(format)
date2.value = moment().add(-1,'days').format(format)
$(date1).attr('disabled',true);
$(date2).attr('disabled',true);
} else if(value==="thismonth"){
date1.value = moment().add('month').startOf('month').format(format)
date2.value = moment().add('month').endOf('month').format(format)
$(date1).removeAttr('disabled',true);
$(date2).removeAttr('disabled',true);
} else if(value==="lastmonth"){
date1.value = moment().add(-1,'month').startOf('month').format('DD/MM/YYYY')
date2.value = moment().add(-1,'month').endOf('month').format('DD/MM/YYYY')
$(date1).attr('disabled',true);
$(date2).attr('disabled',true);
}
})
})
chartPanel.on("chart:render",function(){
//Chartist JS
var tanggal = []
var label = data1.models.map(function(model,index){
return model.get("tanggal")
})
function unique(list) {
var result = [];
$.each(list, function(i, e) {
if ($.inArray(e, result) == -1) result.push(e);
});
return result;
}
var labels = unique(label)
var tshirtv = [];
var casev = [];
var tanggal = [];
var series = data1.models.map(function(model,index){
tanggal[index] = model.get("tanggal");
if(tanggal[index - 1] === model.get("tanggal")){
if(model.get("produk")==="T-Shirt"){
tshirtv[index - 1] = model.get("jumlah");
} else if(model.get("produk")==="Case"){
casev[index - 1] = model.get("jumlah");
}
} else {
if(model.get("produk")==="T-Shirt"){
tshirtv[index] = model.get("jumlah");
casev[index] ="0";
} else if(model.get("produk")==="Case"){
casev[index] = model.get("jumlah");
tshirtv[index] ="0";
}
}
})
tshirtv = tshirtv.filter(()=>true)
casev = casev.filter(()=>true)
if((tshirtv.length !== 1) && (casev.length !== 1)) {
var series = [
{
name : "T-shirt",
data : tshirtv
},
{
name : "Case",
data : casev
}
]
//Line Chart
var data = {
labels : labels,
series : series
}
var option = {
showArea : true,
lineSmooth : false,
showPoint : true,
chartPadding : {
bottom:60,
top:60,
},
axisX : {
showGrid:false,
},
axisY : {
onlyInteger : true,
},
plugins : [
Chartist.plugins.ctAxisTitle({
axisX: {
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: 50
},
textAnchor: 'middle'
},
axisY: {
axisTitle: 'Jumlah Penjualan',
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: 0
},
textAnchor: 'middle',
flipTitle: false
}
}),
Chartist.plugins.ctPointLabels({
textAnchor : "middle"
}),
Chartist.plugins.legend()
]
}
var responsiveOptions = [
[
'screen and (max-width: 640px)', {
showLine: false,
showPoint : true,
axisX: {
labelInterpolationFnc: function(value) {
return value.substr(0,2);
}
}
}
],
[
'screen and (max-width: 360px)', {
showLine: false,
showPoint : true,
height:"100%",
axisX: {
labelInterpolationFnc: function(value) {
return value.substr(0,2);
}
}
}
]
];
new Chartist.Line($('.statistic',this.el)[0],data,option,responsiveOptions)
} else {
//Donut Chart
var data2 = {
labels : ['T-Shirt', 'Case'],
series : [tshirtv[0], casev[0]]
}
var option2 = {
chartPadding : {
top : 0,
},
labelInterpolationFnc : function(value,series){
return value + ": " +data2.series[series].value
},
donut:true,
donutWidth : 60,
plugins : [
Chartist.plugins.legend()
]
}
new Chartist.Pie($('.statistic',this.el)[0],data2,option2)
}
})
chartLayout.on("show", function(){
chartLayout.filterRegion.show(filterPanel)
chartLayout.chartRegion.show(chartPanel)
})
programming.wrapper.show(chartLayout)
} else {
chartPanel = new Chart.notfound()
programming.wrapper.show(chartPanel)
}
}
}
})
Look at Your code:
...
filterPanel.trigger("form:filter" ,firstFilter)
...
filterPanel.on("form:filter", function(data){
var criterion = data
filteredData.filter(criterion)
data1 = filteredData.filter(criterion)
if(data1.length === 0){
$('.warn').finish().slideDown(80,function(){
setTimeout(function(){$('.warn').finish().slideUp(80)},3000)
})
} else {
$('.statistic').fadeOut(100,function(){
chartPanel.trigger("chart:render")
$('.statistic').fadeIn(100)
})
}
})
....
At the beginnig You call trigger. Trigger function cannot find callback (because You don't define it yet). In the next step You define a callback function for trigger form:filter.
You must swap calling trigger and define callback for trigger.
...
filterPanel.on("form:filter", function(data){
var criterion = data
filteredData.filter(criterion)
data1 = filteredData.filter(criterion)
if(data1.length === 0){
$('.warn').finish().slideDown(80,function(){
setTimeout(function(){$('.warn').finish().slideUp(80)},3000)
})
} else {
$('.statistic').fadeOut(100,function(){
chartPanel.trigger("chart:render")
$('.statistic').fadeIn(100)
})
}
});
filterPanel.trigger("form:filter" ,firstFilter)
....
Related
In jsPlumb, I am trying to get the full path between 2 nodes as an array with a single query even if there is multiple nodes in between source and destination. I am currently doing it with a BFS algorithm because I couldn't find anything like that in the documentation the code is
getPath: function (sourceId, targetId) {
var me = this;
var addNode = function addNode(graph, node) {
graph.set(node, {
in: new Set(),
out: new Set()
});
};
var connectNodes = function connectNodes(graph, sourceId, targetId) {
graph.get(sourceId).out.add(targetId);
graph.get(targetId).in.add(sourceId);
};
var buildGraphFromEdges = function buildGraphFromEdges(edges) {
return edges.reduce(function (graph, {
sourceId,
targetId
}) {
if (!graph.has(sourceId)) {
addNode(graph, sourceId);
}
if (!graph.has(targetId)) {
addNode(graph, targetId);
}
connectNodes(graph, sourceId, targetId);
return graph;
}, new Map());
};
var buildPath = function buildPath(targetId, path) {
var result = [];
while (path.has(targetId)) {
var sourceId = path.get(targetId);
result.push({
sourceId,
targetId
});
targetId = sourceId;
}
return result.reverse();
};
var findPath = function findPath(sourceId, targetId, graph) {
if (!graph.has(sourceId)) {
throw new Error('Unknown sourceId.');
}
if (!graph.has(targetId)) {
throw new Error('Unknown targetId.');
}
var queue = [sourceId];
var visited = new Set();
var path = new Map();
while (queue.length > 0) {
var start = queue.shift();
if (start === targetId) {
return buildPath(start, path);
}
for (var next of graph.get(start).out) {
if (visited.has(next)) {
continue;
}
if (!queue.includes(next)) {
path.set(next, start);
queue.push(next);
}
}
visited.add(start);
}
return null;
};
var graph = buildGraphFromEdges(me.jsPlumbContainer.getAllConnections());
var resultPath = findPath(sourceId, targetId, graph);
return resultPath;}
Is there a much better way to implement this ?
example array for my configuration is:
var connections =[
{
"sourceId": "l1",
"targetId": "l2"
},
{
"sourceId": "l2",
"targetId": "l4"
},
{
"sourceId": "l2",
"targetId": "l3"
},
{
"sourceId": "l4",
"targetId": "l5"
}, ]
I need to make a Rickshaw legend where I can make groups of time series.
e.g. I have 20 time series displayed in a graph and I want them to be grouped in 4 groups, named series1, series2, series3, series4. Series1 would contain the first 5 time series in the graph, series2 would contain the 6th to the 10th and so on.
Before I try to add a custom object in my .js to solve my problem someone knows if there is a built in functionality that I couldn't find?
I didn't find anything helpful so I created a personalized version of a multiple legend that works along with the traditional legend.
Unfortunately to update the multiple legend when the standard legend is modified I had to create a myLegend object instead of the default one.
You can use this version in this way:
//you must have a traditional Rickshaw seriesData
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: seriesData
} );
graph.render();
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
var mLegend = new multiLegend( {
graph: graph,
element: document.getElementById('multi_legend'),
multiDivision: [
{
name: "Africa",
indexes: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
}
{
name: "Asia",
indexes: [ 8, 9, 10, 11, 12 ]
},
{
name: "Europe",
indexes: [ 13, 14, 15, 16, 17]
},
{
name: "North America",
indexes: [ 18, 19, 20 ]
}
]
} );
new myToggle( {
graph: graph,
legend: legend,
multiLegend: mLegend
} );
new multiToggle( {
graph: graph,
multiLegend: mLegend,
legend: legend
});
Here's the code:
multiLegend = Rickshaw.Class.create( {
className: 'rickshaw_legend',
initialize: function(args) {
this.element = args.element;
this.graph = args.graph;
this.naturalOrder = args.naturalOrder;
this.seriesGroups = args.multiDivision;
this.element.classList.add(this.className);
this.list = document.createElement('ul');
this.element.appendChild(this.list);
this.render();
// we could bind this.render.bind(this) here
// but triggering the re-render would lose the added
// behavior of the series toggle
this.graph.onUpdate( function() {} );
},
render: function() {
var self = this;
while ( this.list.firstChild ) {
this.list.removeChild( this.list.firstChild );
}
this.lines = [];
var allSeries = this.graph.series;
self.seriesGroups.forEach( function(s) {
var series = allSeries.filter( function(value, index) {
return (s.indexes.indexOf(index)!=-1) ? true : false;
});
series = series.reverse();
self.addLine(s.name, series);
} );
},
addLine: function (name, series) {
var line = document.createElement('li');
line.className = 'line';
if (series.disabled) {
line.className += ' disabled';
}
if (series.className) {
d3.select(line).classed(series.className, true);
}
var swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.backgroundColor = "#0000FF";
line.appendChild(swatch);
var label = document.createElement('span');
label.className = 'label';
label.innerHTML = name;
line.appendChild(label);
this.list.appendChild(line);
line.series = series;
var _line = { element: line, series: series, disabled: false};
if (this.shelving) {
this.shelving.addAnchor(_line);
this.shelving.updateBehaviour();
}
if (this.highlighter) {
this.highlighter.addHighlightEvents(_line);
}
this.lines.push(_line);
return line;
}
} );
multiToggle = function(args) {
this.graph = args.graph;
this.multiLegend = args.multiLegend;
this.legend = args.legend;
var self = this;
this.addAnchor = function(line) {
var anchor = document.createElement('a');
anchor.innerHTML = '✔';
anchor.classList.add('action');
line.element.insertBefore(anchor, line.element.firstChild);
anchor.onclick = function(e) {
if (line.disabled) {
line.series.forEach( function(serie) {
serie.enable();
});
line.element.classList.remove('disabled');
line.disabled = false;
self.legend.lines
.filter(function(value) {
return (line.series.indexOf(value.series)!=-1) ? true : false;
})
.forEach( function(l) {
l.element.classList.remove('disabled');
l.disabled = false;
});
} else {
if (this.graph.series.filter(function(s) { return !s.disabled }).length <= 1) return;
line.series.forEach( function(serie) {
serie.disable();
});
line.element.classList.add('disabled');
line.disabled = true;
self.legend.lines
.filter(function(value) {
return (line.series.indexOf(value.series)!=-1) ? true : false;
})
.forEach( function(l) {
l.element.classList.add('disabled');
l.disabled = true;
});
}
self.graph.update();
}.bind(this);
var label = line.element.getElementsByTagName('span')[0];
label.onclick = function(e){
var disableAllOtherLines = line.disabled;
if ( ! disableAllOtherLines ) {
for ( var i = 0; i < self.multiLegend.lines.length; i++ ) {
var l = self.multiLegend.lines[i];
if ( line.series === l.series ) {
// noop
} else if ( l.series.disabled ) {
// noop
} else {
disableAllOtherLines = true;
break;
}
}
}
// show all or none
if ( disableAllOtherLines ) {
// these must happen first or else we try ( and probably fail ) to make a no line graph
line.series.forEach( function(serie) {
serie.enable();
});
line.element.classList.remove('disabled');
line.disabled = false;
self.legend.lines
.filter(function(value) {
return (line.series.indexOf(value.series)!=-1) ? true : false;
})
.forEach( function(l) {
l.element.classList.remove('disabled');
l.disabled = false;
});
self.multiLegend.lines.forEach(function(l){
if ( line.series === l.series ) {
// noop
} else {
l.series.forEach( function(serie) {
serie.disable();
});
l.element.classList.add('disabled');
l.disabled = true;
self.legend.lines
.filter(function(value) {
return (l.series.indexOf(value.series)!=-1) ? true : false;
})
.forEach( function(l2) {
l2.element.classList.add('disabled');
l2.disabled = true;
});
}
});
} else {
self.multiLegend.lines.forEach(function(l){
l.series.forEach( function(serie) {
serie.enable();
});
l.element.classList.remove('disabled');
l.disabled = false;
self.legend.lines
.filter(function(value) {
return (l.series.indexOf(value.series)!=-1) ? true : false;
})
.forEach( function(l2) {
l2.element.classList.remove('disabled');
l2.disabled = false;
});
});
}
self.graph.update();
};
};
if (this.multiLegend) {
var $ = jQuery;
if (typeof $ != 'undefined' && $(this.multiLegend.list).sortable) {
$(this.multiLegend.list).sortable( {
start: function(event, ui) {
ui.item.bind('no.onclick',
function(event) {
event.preventDefault();
}
);
},
stop: function(event, ui) {
setTimeout(function(){
ui.item.unbind('no.onclick');
}, 250);
}
});
}
this.multiLegend.lines.forEach( function(l) {
self.addAnchor(l);
} );
}
this._addBehavior = function() {
this.graph.series.forEach( function(s) {
s.disable = function() {
if (self.graph.series.length <= 1) {
throw('only one series left');
}
s.disabled = true;
};
s.enable = function() {
s.disabled = false;
};
} );
};
this._addBehavior();
this.updateBehaviour = function () { this._addBehavior() };
};
myToggle = function(args) {
this.graph = args.graph;
this.legend = args.legend;
this.multiLegend = args.multiLegend;
var self = this;
this.addAnchor = function(line) {
var anchor = document.createElement('a');
anchor.innerHTML = '✔';
anchor.classList.add('action');
line.element.insertBefore(anchor, line.element.firstChild);
anchor.onclick = function(e) {
if (line.series.disabled) {
line.series.enable();
line.element.classList.remove('disabled');
} else {
if (this.graph.series.filter(function(s) { return !s.disabled }).length <= 1) return;
line.series.disable();
line.element.classList.add('disabled');
self.multiLegend.lines.forEach( function(l) {
if(l.series.indexOf(line.series)!=-1) {
l.element.classList.add('disabled');
l.disabled = true;
}
});
}
self.graph.update();
}.bind(this);
var label = line.element.getElementsByTagName('span')[0];
label.onclick = function(e){
var disableAllOtherLines = line.series.disabled;
if ( ! disableAllOtherLines ) {
for ( var i = 0; i < self.legend.lines.length; i++ ) {
var l = self.legend.lines[i];
if ( line.series === l.series ) {
// noop
} else if ( l.series.disabled ) {
// noop
} else {
disableAllOtherLines = true;
break;
}
}
}
// show all or none
if ( disableAllOtherLines ) {
// these must happen first or else we try ( and probably fail ) to make a no line graph
line.series.enable();
line.element.classList.remove('disabled');
self.legend.lines.forEach(function(l){
if ( line.series === l.series ) {
// noop
} else {
l.series.disable();
l.element.classList.add('disabled');
}
});
self.multiLegend.lines.forEach( function(l) {
l.element.classList.add('disabled');
l.disabled = true;
});
} else {
self.legend.lines.forEach(function(l){
l.series.enable();
l.element.classList.remove('disabled');
});
}
self.graph.update();
};
};
if (this.legend) {
var $ = jQuery;
if (typeof $ != 'undefined' && $(this.legend.list).sortable) {
$(this.legend.list).sortable( {
start: function(event, ui) {
ui.item.bind('no.onclick',
function(event) {
event.preventDefault();
}
);
},
stop: function(event, ui) {
setTimeout(function(){
ui.item.unbind('no.onclick');
}, 250);
}
});
}
this.legend.lines.forEach( function(l) {
self.addAnchor(l);
} );
}
this._addBehavior = function() {
this.graph.series.forEach( function(s) {
s.disable = function() {
if (self.graph.series.length <= 1) {
throw('only one series left');
}
s.disabled = true;
};
s.enable = function() {
s.disabled = false;
};
} );
};
this._addBehavior();
this.updateBehaviour = function () { this._addBehavior() };
};
I have a controller that works fine on initial load. It calls user [0] data and everything processes fine. When I change dropdown, I want to call the same function, but I cannot get the entire controller to reload. It starts from the function call and leaves undefined in places where it pulls correct information (linkToken, etc) on initial load. Is there a way I can get it to reload all data from the controller instead of just from the function?
After calling the testchange() from the view to pass in the new data, I get :
TypeError: Cannot read property 'locations' of undefined
at h.$scope.updateLocations (refillController.js:261)
at refillController.js:73
But, when I call the original getRefills() that is ran on the initial page load I get the same error. How can I define these so the load after the onchange(0)?
angular.module('FinalApp.Controllers').controller('refillController', function ($rootScope, $scope, $location, $modal, userService, dependentsService, accountService, sharedCollections, configurationService, refillsService) {
$scope.user = userService.GetUserInformation();
$scope.userInfoArr = [];
//$scope.tests.push({'Name':$scope.user.FirstName, 'LinkToken':$scope.user.LinkToken});
$scope.userInfoArr = $scope.user.Dependants.map(function(item){return {'Name':item.FirstName, 'LinkToken':item.LinkToken}});
$scope.userInfoArr.splice(0, 0, {'Name': $scope.user.FirstName, 'LinkToken': $scope.user.LinkToken});
console.log($scope.userInfoArr);
$scope.finUserInfoArr = $scope.userInfoArr[0].LinkToken;
$scope.billingInfo = null;
$rootScope.showNavbar = true;
$scope.selectedMethod = null;
$scope.location = null;
$scope.payment = null;
$scope.refills = [];
$scope.deliverTypes = [];
$scope.locations = [];
$scope.payments = [];
$scope.allSelected = false;
$scope.loadingBillingInfo = false;
$scope.isMailOrder = false;
//Detect Mobile Switch Refill List To Grid
if(window.innerWidth <= 800) {
$scope.view = "Grid";
} else {
$scope.view = "List";
}
$scope.changeViewToList = function () {
$scope.view = "List";
};
$scope.changeViewToGrid = function () {
$scope.view = "Grid";
};
$scope.testchange = function(selectedTest) {
$scope.getRefills(selectedTest);
console.log(selectedTest);
};
$scope.getRefills = function (linkToken) {
$scope.allSelected = false;
$scope.loading = true;
refillsService.GetRefills(
linkToken,
$scope.selectedMethod,
$scope.location,
$scope.payment
).then(function (data) {
$scope.refills = [];
_.each(data.Prescriptions, function (item) {
fillRefills(item);
});
fillDeliverTypes(data.DeliveryTypes);
if (!$scope.selectedMethod)
$scope.selectedMethod = data.DeliveryTypeId;
if (!$scope.location)
$scope.location = data.PickupLocationId;
if (!$scope.payment)
$scope.payment = data.PaymentTypeId;
$scope.loading = false;
$scope.updateLocations();
})["catch"](function (error) {
console.log(error);
$scope.loading = false;
alertify.alert(configurationService.ErrorMessage("getting your refills", error.Message));
});
};
var fillRefills = function (item) {
//TODO-CallDoc temp fix
if (item.RefillClass == "CALL_DOCTOR") {
item.NextRefillDate = '1900-01-01T00:00:00'
}
var parsedDate = checkDate(moment(item.NextRefillDate).format('L'));
var lastrefill = checkDate(moment(item.LastDispenseDate).format('L'));
var expireDate = checkDate(moment(item.ExpirationDate).format('L'));
var status = (item.RefillStatus.indexOf("After") == -1) ? item.RefillStatus : "Refill " + item.RefillStatus;
$scope.refills.push({
selected: false,
rx: item.ScriptNo,
name: item.DrugName,
dose: item.UnitsPerDose,
dir: item.Instructions,
nextfill: parsedDate,
lastfill: lastrefill,
refillsLeft: item.NumRefillsLeft,
status: status,
msg: item.RefillMessage,
canSelect: item.IsRefillable,
refillClass: item.RefillClass,
lastDispenseQty: item.LastDispenseQty,
DaysSupply: item.DaysSupply,
expireDate: expireDate,
copayAmt: item.CopayAmt,
drFirstName: item.DoctorFirstName,
drLastName: item.DoctorLastName,
writtenQty: item.WrittenQty
});
};
var checkDate = function (date) {
if (date == "01/01/1900") return "N/A";
if (date == "Invalid Date") return "";
return date;
};
var fillDeliverTypes = function (deliverTypes) {
$scope.deliverTypes = [];
_.each(deliverTypes, function (item) {
$scope.deliverTypes.push({
id: item.DeliveryTypeId,
name: item.DeliveryTypeName,
locations: item.PickupLocations,
payments: item.PaymentTypes
});
});
};
var getBillingInfo = function () {
$scope.loadingBillingInfo = true;
accountService.GetCreditCardInfo().then(function (data) {
$scope.billingInfo = data;
$scope.loadingBillingInfo = false;
})["catch"](function (error) {
$scope.loadingBillingInfo = false;
alertify.alert(configurationService.ErrorMessage("getting account information", error.Message));
});
};
var getAccountInfo = function () {
accountService.GetAccountInfo().then(function (data) {
if (data.StatusCode == "SUCCESS") {
$scope.user = data;
userService.SaveUserInformation(data);
if ($scope.user.IsLinked) {
$rootScope.enableMyRefills = true;
$rootScope.enableMyReports = true;
window.location.hash = "#/refills";
} else {
$rootScope.enableMyRefills = false;
$rootScope.enableMyReports = true;
}
} else {
alertify.alert(configurationService.ErrorMessage("getting account information", data.StatusMessage));
}
})["catch"](function (error) {
alertify.alert(configurationService.ErrorMessage("getting account information", error.Message));
});
};
var openModal = function (viewUrl, controllerUrl, size, payload) {
var modalInstance = $modal.open({
templateUrl: viewUrl,
controller: controllerUrl,
size: size,
resolve: {
data: function () {
return payload;
}
}
});
return modalInstance;
};
$scope.toggleRxSelection = function(rx) {
if (rx.canSelect) {
rx.selected = !rx.selected;
$scope.evaluateAllSelected();
}
};
$scope.selectAll = function (data) {
// $scope.allSelected = allSelected;
_.each($scope.refills, function (x) {
if (x.canSelect) x.selected = data;
});
};
$scope.evaluateAllSelected = function () {
var count = _.countBy(_.where($scope.refills, {canSelect:true}), function(refill) {
return refill.selected ? 'selected' : 'not';
});
$scope.allSelected = (count.not === undefined);
};
$scope.openEditCreditCardInfo = function () {
var payload = ($scope.billingInfo != null && $scope.billingInfo != undefined)
&& $scope.billingInfo.CardNumber != "" ? $scope.billingInfo : {};
if (payload != {}) {
payload.ExpMonth = {id: parseInt(payload.ExpMonth)};
payload.ExpYear = {id: parseInt(payload.ExpYear)};
}
openModal('app/views/editAccount/billingInformation.html', "billingInformationController", "xlg", payload).result.then(function () {
getAccountInfo();
getBillingInfo();
}, function () {
getBillingInfo();
});
};
$scope.openConfirmOrder = function () {
var refillsSelected = _.where($scope.refills, {selected: true});
var location = _.findWhere($scope.locations, {PickupLocationId: $scope.location});
var payment = _.findWhere($scope.payments, {PaymentTypeId: $scope.payment});
var deliver = _.findWhere($scope.deliverTypes, {id: $scope.selectedMethod});
if (refillsSelected.length == 0) {
alertify.error("You need to select at least one refill");
return;
}
if (deliver.id == 10001 && !$scope.user.IsCreditCardOnFile) {
alertify.error("Need credit card on file for mail order");
return;
}
sharedCollections.setRefills(refillsSelected);
sharedCollections.setLocation(location);
sharedCollections.setPayment(payment);
sharedCollections.setDeliver(deliver);
openModal('app/views/refills/confirmOrder.html', "confirmOrderController", "xlg").result.then(function () {
$scope.billingInfo = accountService.GetCreditCardInfo();
$scope.getRefills();
}, function () {
//$scope.billingInfo = accountService.GetCreditCardInfo();
//getRefills();
});
};
$scope.showRefill = function (rx) {
var data = {rx: rx, refills: $scope.refills};
openModal('app/views/refills/showRefills.html', "refillsCarrousel", "xlg", data).result.then(function () {
$scope.evaluateAllSelected();
}, function () {
$scope.evaluateAllSelected();
});
};
$scope.updateLocations = function () {
$scope.locations = _.findWhere($scope.deliverTypes, {id: $scope.selectedMethod}).locations;
$scope.payments = _.findWhere($scope.deliverTypes, {id: $scope.selectedMethod}).payments;
setLocationAndPayment();
};
var setLocationAndPayment = function () {
if ($scope.locations.length == 1) {
$scope.location = $scope.locations[0].PickupLocationId;
}
if ($scope.payments.length == 1) {
$scope.payment = $scope.payments[0].PaymentTypeId;
}
//check for mail order
($scope.selectedMethod == 10001 && !$scope.payment) ? $scope.isMailOrder = true : $scope.isMailOrder = false;
};
$scope.getRefills($scope.finUserInfoArr);
getBillingInfo();
});
Check if your refillsService returns correct data, it could be that $scope.refills remains empty array.
In SAPUI5 I have a Model ("sModel") filled with metadata.
In this model I have a property "/aSelectedNumbers".
I also have a panel, of which I want to change the visibility depending on the content of the "/aSelectedNumbers" property.
update
first controller:
var oModelMeta = cv.model.recycleModel("oModelZAPRegistratieMeta", that);
//the cv.model.recycleModel function sets the model to the component
//if that hasn't been done so already, and returns that model.
//All of my views are added to a sap.m.App, which is returned in the
//first view of this component.
var aSelectedRegistratieType = [];
var aSelectedDagdelen = ["O", "M"];
oModelMeta.setProperty("/aSelectedRegistratieType", aSelectedRegistratieType);
oModelMeta.setProperty("/aSelectedDagdelen", aSelectedDagdelen);
First Panel (Which has checkboxes controlling the array in question):
sap.ui.jsfragment("fragments.data.ZAPRegistratie.Filters.RegistratieTypeFilter", {
createContent: function(oInitData) {
var oController = oInitData.oController;
var fnCallback = oInitData.fnCallback;
var oModel = cv.model.recycleModel("oModelZAPRegistratieMeta", oController);
var oPanel = new sap.m.Panel( {
content: new sap.m.Label( {
text: "Registratietype",
width: "120px"
})
});
function addCheckBox(sName, sId) {
var oCheckBox = new sap.m.CheckBox( {
text: sName,
selected: {
path: "oModelZAPRegistratieMeta>/aSelectedRegistratieType",
formatter: function(oFC) {
if (!oFC) { return false; }
console.log(oFC);
return oFC.indexOf(sId) !== -1;
}
},
select: function(oEvent) {
var aSelectedRegistratieType = oModel.getProperty("/aSelectedRegistratieType");
var iIndex = aSelectedRegistratieType.indexOf(sId);
if (oEvent.getParameters().selected) {
if (iIndex === -1) {
aSelectedRegistratieType.push(sId);
oModel.setProperty("/aSelectedRegistratieType", aSelectedRegistratieType);
}
} else {
if (iIndex !== -1) {
aSelectedRegistratieType.splice(iIndex, 1);
oModel.setProperty("/aSelectedRegistratieType", aSelectedRegistratieType);
}
}
// arrays update niet live aan properties
oModel.updateBindings(true); //******** <<===== SEE HERE
if (fnCallback) {
fnCallback(oController);
}
},
width: "120px",
enabled: {
path: "oModelZAPRegistratieMeta>/bChanged",
formatter: function(oFC) {
return oFC !== true;
}
}
});
oPanel.addContent(oCheckBox);
}
addCheckBox("Presentielijst (dag)", "1");
addCheckBox("Presentielijst (dagdelen)", "2");
addCheckBox("Uren (dagdelen)", "3");
addCheckBox("Tijd (dagdelen)", "4");
return oPanel;
}
});
Here is the panel of which the visibility is referred to in the question. Note that it DOES work after oModel.updateBindings(true) (see comment in code above), but otherwise it does not update accordingly.
sap.ui.jsfragment("fragments.data.ZAPRegistratie.Filters.DagdeelFilter", {
createContent: function(oInitData) {
var oController = oInitData.oController;
var fnCallback = oInitData.fnCallback;
var oModel = cv.model.recycleModel("oModelZAPRegistratieMeta", oController);
var oPanel = new sap.m.Panel( {
content: new sap.m.Label( {
text: "Dagdeel",
width: "120px"
}),
visible: {
path: "oModelZAPRegistratieMeta>/aSelectedRegistratieType",
formatter: function(oFC) {
console.log("visibility");
console.log(oFC);
if (!oFC) { return true; }
if (oFC.length === 0) { return true; }
return oFC.indexOf("2") !== -1;
}
}
});
console.log(oPanel);
function addCheckBox(sName, sId) {
var oCheckBox = new sap.m.CheckBox( {
text: sName,
selected: {
path: "oModelZAPRegistratieMeta>/aSelectedDagdelen",
formatter: function(oFC) {
if (!oFC) { return false; }
console.log(oFC);
return oFC.indexOf(sId) !== -1;
}
},
select: function(oEvent) {
var aSelectedDagdelen = oModel.getProperty("/aSelectedDagdelen");
var iIndex = aSelectedDagdelen.indexOf(sId);
if (oEvent.getParameters().selected) {
if (iIndex === -1) {
aSelectedDagdelen.push(sId);
oModel.setProperty("/aSelectedDagdelen", aSelectedDagdelen);
}
} else {
if (iIndex !== -1) {
aSelectedDagdelen.splice(iIndex, 1);
oModel.setProperty("/aSelectedDagdelen", aSelectedDagdelen);
}
}
if (fnCallback) {
fnCallback(oController);
}
},
enabled: {
path: "oModelZAPRegistratieMeta>/bChanged",
formatter: function(oFC) {
return oFC !== true;
}
},
width: "120px"
});
oPanel.addContent(oCheckBox);
}
addCheckBox("Ochtend", "O", true);
addCheckBox("Middag", "M", true);
addCheckBox("Avond", "A");
addCheckBox("Nacht", "N");
return oPanel;
}
});
The reason that the model doesn´t trigger a change event is that the reference to the Array does not change.
A possible way to change the value is to create a new Array everytime you read it from the model:
var newArray = oModel.getProperty("/aSelectedNumbers").slice();
// do your changes to the array
// ...
oModel.setProperty("/aSelectedNumbers", newArray);
This JSBin illustrates the issue.
Am still getting the hang of promises..
Here are the models of the db collections involved:
var itemSchema = new Schema({
label : String,
tag : { "type": Schema.ObjectId, "ref": "tag" }
});
var tagSchema = new Schema({
label : String,
});
And here's the series of Promises (map, map, map, join):
Right now, the Promise.join saves&completes before the 'items' map finishes running, and so the 'senders' map doesn't include the 'itemsArray' javascriptObject on save .. how can this be resolved?
var reqItems = req.body.items;
var itemsArray = [];
var items = Promise.map(reqItems,function(element){
var existingItem = Models.Item.findOneAsync({ "label": element });
existingItem.then(function (value) {
if ( (existingItem.fulfillmentValue != null) ) { // if this item exists
var itemObject = [
{ "item" : existingItem.fulfillmentValue._id },
{ "label" : existingItem.fulfillmentValue.label }
{ "tag" : existingItem.fulfillmentValue.tag }
];
itemsArray.push(itemObject);
} else { // first instance of this item .. create newItem
var existingTag = Models.Tag.findOneAsync({ "label": element });
existingTag.then(function (value) {
if ( (existingTag.fulfillmentValue != null) ) { // if this tag exists
var newItem = new Models.Item(
{
label : element,
tag : existingTag.fulfillmentValue._id,
}
);
newItem.save(function (err) { // save the newItem with existing tag
console.log(err);
var newSavedItem = Models.Item.findOneAsync({ "label": element });
newSavedItem.then(function (value) { // ensure existence of newItem
var itemObject = [
{ "item" : newSavedItem.fulfillmentValue._id },
{ "label" : newSavedItem.fulfillmentValue.label },
{ "tag" : newSavedItem.fulfillmentValue.tag }
];
itemsArray.push(itemObject); // push item to array
});
});
} else { // else this tag does not exist
var newTag = new Models.Tag(
{
label : element
}
);
newTag.save(function (err) {
console.log(err);
var newSavedTag = Models.Tag.findOneAsync({ "label": element });
newSavedTag.then(function (value) { // ensure existence of newTag
if ( (newSavedTag.fulfillmentValue != null) ) {
var newItem = new Models.Item(
{
label : element,
tag : newSavedTag.fulfillmentValue._id,
}
);
newItem.save(function (err) {
console.log(err);
var newSavedItem = Models.Item.findOneAsync({ "label": element });
newSavedItem.then(function (value) { // ensure existence of newItem
var itemObject = [
{ "item" : newSavedItem.fulfillmentValue._id },
{ "label" : newSavedItem.fulfillmentValue.label },
{ "tag" : newSavedItem.fulfillmentValue.tag }
];
itemsArray.push(itemObject); // push item to array
}); // newSavedItem.then
}); // newItem.save
} // if newSavedTag.isFulfilled
}); // newSavedTag.then
}); // newTag.save
} // else tag does not exist
}); // existingTag.then
} // first instance of this item .. create newItem
}); // existingItem.then
itemObject = null; // reset for map loop
}); // Promise.map itemsArray
var receivers = Promise.map(receiverArray,function(element){
return Promise.props({
username : element
});
});
var senders = Promise.map(senderArray,function(element){
return Promise.props({
username : element,
items : itemsArray
});
});
Promise.join(receivers, senders, function(receivers, senders){
store.receivers = receivers;
store.senders = senders;
var saveFunc = Promise.promisify(store.save, store);
return saveFunc();
}).then(function(saved) {
console.log(saved);
res.json(saved);
})...error handling...});
Yes that can be massively simplified, although your problem was probably just forgetting to return anything to the first mapper (and the massive wasteland of useless fulfillmentValue code).
var reqItems = req.body.items;
var items = Promise.map(reqItems, function(element) {
return Models.Item.findOneAsync({ "label": element }).then(function(item) {
if (item != null) {
return item;
} else {
return Models.Tag.findOneAsync({ "label": element }).then(function(tag) {
if (tag == null) {
var newTag = new Models.Tag({label: element});
return newTag.saveAsync().then(function() {
return Models.Tag.findOneAsync({ "label": element });
})
}
return tag;
}).then(function(tag) {
var newItem = new Models.Item({
label: element,
tag: tag._id
});
return newItem.saveAsync().then(function() {
return Models.Item.findOneAsync({ "label": element });
});
})
}
});
});
var receivers = Promise.map(receiverArray, function(element){
return Promise.props({
username : element
});
});
var senders = Promise.map(senderArray, function(element){
return Promise.props({
username : element,
items : itemsArray
});
});
Promise.join(receivers, senders, items, function(receivers, senders, items) {
store.receivers = receivers;
store.senders = senders;
store.items = items;
return store.saveAsync().return(store);
}).then(function(store) {
console.log("saved store", store);
res.json(store);
}).catch(Promise.OperationalError, function(e) {
console.log("error", e);
res.send(500, "error");
});