Kendo Progress Bar Modifications - angularjs

Inside a Kendo Tree List for Angular Js I have added a Graph as a kendo template.
<script id="progressStatus" type="text/x-kendo-template">
<div ng-if="'#:Status#' == 'Loading'">
<div kendo-progress-bar="progressBar1" k-min="0" k-max="100" k-value="#:Percentage#" style="width: 100%;"></div>
</div>
</script>
And I bind it to the tree list as part of column declaration
{ field: "Status", template: $("#progressStatus").html(), width: "170px" }
So far good. And I am able to display the value in UI.
However I am not sure how to show following
How to make it of type percent, i tried with k-type='percent' but no luck
If Percentage > 50 show the graph in yellow and text (50%) in red

Unfortunately, some options seems not to work with angular directives. I could not get to work k-type (like you). In my dojo that attribute seems to break the widget. After checking this page, I could use type the following way:
<div kendo-progress-bar="progressBar1" k-options="progressBarOptions" style="width: 100%;"></div>
.controller("MyController", function($scope) {
$scope.dataSource = [
'foo', 'bar', 'baz'
];
$scope.progressBarOptions = {
min: 0,
max: 100,
value: 50,
type: "percent"
};
});
Demo. That will make percent type work.
Now, changing the color of the widget based on the value is another problem. The ProgressBar don't have any kind templates and it is poor in events(only complete and change). It seems that your bar doesn't changes it's value, it's is static, right? So I tried to realize a way to call change event with animation which should call change after being complete. It would be like an initialization event. But, animation doesn't seems to work either. I tried with k-animation and in the init options, but no luck. Double checked for typos but I'm sure that wasn't the case. It's a shame.
Anyway, you can use the ugly and non-straightforward way using a function which you should call in your grid's dataBound event:
var changeBarColor = function()
{
$('[data-role="progressbar"]').each(function() {
$(this).find(".k-state-selected").addClass(
$(this).data("kendoProgressBar").value() < 50
? "yellow-bar"
: "red-bar"
);
});
};
Demo. Again: It's a shame the widget lacks of such a simple and useful feature like that.
I hope I'm wrong but that is the far I could get on this. Good luck.

Related

ng-style not refreshing dynamically

I have an md-card with this code:
<md-card ng-style="{ width: pageWidth > 900 ? '40vw' : '80vw' }">...</md-card>
pageWidth is a $scope variable bound to $(window).width(). Here is the code for that:
$scope.pageWidth = $(window).width();
$(window).resize(() => {
$scope.pageWidth = $(window).width();
console.log('page width: ' + $scope.pageWidth);
})
$(document).ready(() => {
$(window).resize(() => {
$scope.pageWidth = $(window).width();
console.log('page width: ' + $scope.pageWidth);
})
})
The style is applied correctly when the page loads, but not when I manually resize the page. As you can see in the second code block, I added a console.log statement to the handlers, so I know that $scope.pageWidth is updating with every pixel of width I change. However, the width of the md-card never changes from one to the other. What's going on here?
And before you mark this as a duplicate, people have asked this before, but not in a way where their answers apply to my situation.
Sorry, I'm not posting an answer for this other then that you have a typo in first line should be:
<md-card ng-style="{ width: pageWidth > 900 ? '40vw' : '80vw' }">...</md-card>
But from what I can see what you are doing can be done much more efficiently using normal CSS - no need to put javascript logic for that. Also I would advise using AngularJS $window (you will need to inject it) instead of global window object and I'm against using Jquery in Angular applications and Jquery DOM manipulations unless it's really really (and I will say again really) necessary.
Check this link about media queries:
https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
You will see that you can easily check max-width and max-height, also min-width/height and tons of different things that might solve your problems with pure CSS and no need for Javascript/Jquery mixed with AngularJS.
Your CSS would be something like:
#media screen and (max-width: 900px) {
md-card {
width: 80vw;
}
}
#media screen and (min-width: 901px) {
md-card {
width: 40vw;
}
}
Of course this would be globally on all md-card elements if you need it more specific add classes on each element and change media queries.

ExtJS: Issue updating HTML on bound form

Please refer to the following fiddle: Binding HTML Issue
When you select a row from the combobox on the left panel, it prints the bound value, along with some HTML in the form on right. When you then click on the button labeled as 'Test Update' it first clears the bound value in the drop down, and then is supposed to update the HTML to clear it, as well.
Problem is, that the update for the displayfield referenced in the Ext.ComponentQuery.query does not work in this order. If I do the update first in the fiddle it works, but if I try this in my actual app, it does not (in my app the setValue on the combobox DOES work though, but then leaves the HTML label - which I want to clear).
An ideas as to why this behavior is occurring would be most welcome.
You probably would want to use a formula for that, it simplifies the logic behind it.
viewModel: {
formulas: {
foo: function(get) {
var sel = get('peopleComboRef.selection');
return sel ? ('HTML Label: ' + sel.get('name')) : '';
}
}
},
then bind this formula to your displayfield.
{
xtype: 'displayfield',
itemId: 'displayTest',
bind: {
html: '{foo}'
}
}
fiddle: https://fiddle.sencha.com/#fiddle/24f5&view/editor

Ext JS Progress Bar - text align to center

Just started using progressbarwidget, I want the text from my textTpl to be center aligned within the progress bar at all times regardless of what percentage the bar is at, when I mean centered I mean the center of the progress bar and not center of the progress value. See fiddle below and attached image
https://fiddle.sencha.com/#fiddle/1dm7
I seen a reference on another thread to set position : relative, this does set the text to the center of the bar but doing so means the bar does not show the progress anymore. I see when the progress bar is created it has 2 divs, containing the following classes, x-progress-text and x-progress-bar, both contain the text value.
Thanks in advance
You can extend ProgressBarWidget, and override the template, like:
Ext.define('Fiddle.view.ProgressBarWidget', {
extend: 'Ext.ProgressBarWidget',
xtype: 'fiddle-progressbarwidget',
template: [{
reference: 'backgroundEl'
}, {
reference: 'barEl'
}, {
reference: 'textEl',
style: {
left: 0,
right: 0
}
}],
});
Working example: https://fiddle.sencha.com/#fiddle/1dn4
The definitive solution is to add an onResize handler on the progress bar container:
onResize: function () {
var me = this,
progressBar = me.down('progressbarwidget');
// Set text width to element width so that it can be centered
progressBar.setWidth(progressBar.el.getWidth());
}
This idea is copied from what happens in Ext.grid.column.Widget.onResize().
The solution from user CD.. doesn't work (nor does the one in user2751034 comment)
in the case you have two-color-text, like in Classic theme:
even if you reproduce the template in Sencha sources (with textEl children of barEl):

Angularjs ui-sortable - _connectedSortables is undefined

I have 2 sortable lists and I'm trying to connect them so that I can drag items from one list to the other. When I drag an item I get an error in sortable.js. callbacks.update is referencing ui.item.sortable._connectedSortables but it is undefined so when it gets to the getElementScope function, it throws the error.
UPDATE
I little more background as to how I got here. Initially, I had this working. I setup a draggable list and connected it to the sortable list and all was working fine. The issue I had then was when dragging within the sortable list, the model wasn't getting updated. Once I added the ui-sortable tag the model started getting updated when reordering the list, but after that change is when the previous mentioned error started happening. The differences between the 2 pieces of code are in the first example I am setting up the sortable like this:
$('#testQuestionsTEI').sortable({//code});
and there was no ui-sortable attribute in the markup. Now I have ui-sortable="sortable" in the markup and have $scope.sortable = {//code}.
The first list I have is the accepting list.
<div id ="testQuestionsTEI" class="connectedSortable" ui-sortable="sortable" ng-model="test.questions" style="overflow-x:auto; overflow-y: scroll">
<div class="TestQuestion" ng-repeat="currQuestionObj in test.questions" style="border:1px solid;padding:7px 7px 7px 7px;margin-top:3px;margin-bottom:3px">
<!--do some stuff-->
</div>
</div>
The js to setup the sortable is here...
$scope.sortable = {
placeholder: 'questionPlaceholderTEI',
connectWith: '.connectedSortable',
start: function (event, ui) {
ui.item.startPos = ui.item.index(); //add startPos to item to use in stop event
},
stop: function (event, ui) {
//Do stuff
}
},
update: function (event, ui) {
//Do stuff
}
};
The 2nd list is built after an ajax call and the html for it is...
<div id="SearchResultItems" ui-sortable="sortable" class="col-md-12 connectedSortable" style="border:1px solid;padding:0 5px 0 5px;" ng-cloak>
<div class="SearchResultItem" index="{{currQuestionObj.id}}" QuestionID="{{currQuestionObj.questionId}}" ngc-done="'setupDraggableItems'" ng-repeat="currQuestionObj in ItemSearchResult.questions" style="border:1px solid;padding:7px 7px 7px 7px;margin-top:3px;margin-bottom:3px" >
<!--more stuff-->
</div>
After the data is returned I setup the draggable and sortable
function setupDraggableItems() {
$('div.SearchResultItem').draggable({
revert: 'clone',
scroll: false,
helper: 'clone',
cursor: 'move',
appendTo: 'body',
connectToSortable: '#testQuestionsTEI',
});
$('#SearchResultItems').sortable({
placeholder: 'questionPlaceholderTEI',
connectWith: '.connectedSortable'
});
}
I have also tried without the .draggable and I get a different error. In callbacks.update there is a reference to ui.item.sortable.isCanceled() and the error is "Object doesn't support property or method 'isCanceled'
I found that the problem was that when creating the sortables the 2 different ways I was doing them were actually different implementations. One was using Jquery-ui directly and the other was angular's ui-sortable. So I went back to using $('#testQuestionsTEI').sortable which users Jquery-ui. The other issue where the model wasn't getting updated was fixed by calling $scope.$apply().

Updating NVD3 /D3 chart as per user input radio button

http://nvd3.org/examples/cumulativeLine.html
This example show 4 lines chart. What i want to achieve below.
currently, Series 1, Series 2, Series 3, Series 4 (Charts and Respective legends)
I want keep Series 1, Series 2, Series 3 as common
and I have few radio buttons(Outside chart Area) like Series 5, Series 6, Series 7 and on and on.
Now clicking on those radio button i want to show respective chart and common charts(in this case series 1 ,2 and 3)
for Example
Series 5 radio button clicked
Now Series 1, Series 2, Series 3, Series 5 is shown, [This would removed chart3 legend-chart and add legend-chart of Series 5].
I am trying to achieve above in AngularJS and NVD3 Directive. But i am ok i am known to D3 code logic i should be able to change to angular way. Providing Angular work around is warm welcomed.
[Update]
Strange, instead of cumulative i used simple line chart. I changed the data and chart is being updated as anticipated. I dont what is wrong with cumulative. Any Idea?
With angularjs you can try angular-nvd3 directive. It allows you to manipulate with chart data and chart options via JSON, like:
//html
<nvd3 options="options" data="data"></nvd3>
//javascript
$scope.options = { /*some options*/ }
$scope.data = [ /*some data*/ ]
So, in your case, we just extend this approach to when we interactively update data. We can write something like (using checkboxes):
//html
<div ng-repeat="series in initData">
<input type="checkbox" ng-model="checkboxes[series.key]" ng-init="checkboxes[series.key]=true" ng-change="onchange()"/>{{series.key}}
</div>
<nvd3 options="options" data="data"></nvd3>
where initData is a whole static dataset. And in controller
//javascript
$scope.options = { /*some options*/ }
$scope.initData = [
{
key: "Long",
mean: 250,
values: [ ... ]
},
...
];
$scope.data = angular.copy($scope.initData);
$scope.checkboxes = {};
$scope.onchange = function(){
$scope.data = [];
angular.forEach($scope.initData, function(value, index){
if ($scope.checkboxes[value.key]) $scope.data.push(value);
})
}
See live example: http://plnkr.co/edit/ZLcS6M?p=preview
Note: angular-nvd3
http://embed.plnkr.co/tsJntqq5YJnNUGK6goLZ/preview
See plunkr, I did for a button adding a new serie so it shouldn't have too different just changing for the radio. Notice that if you are getting the data from Web Services or similar resources you probably have to redraw the graph
See https://github.com/krispo/angular-nvd3/issues/37
In the directive
<nvd3 options="options" data="data" api="api"></nvd3>
In the Controller
$scope.api.refresh();
Hope this help

Resources