I am having a popup and it position is set dynamically according to the screen but when the number of the label increase the popup create problem as ones its show in upper side then when the label goes top on the scolling window it suppose to come down but its not coming down.
var position= popup.offsetTop;
alert("popupTop"+position);
var positionpop=popup.offsetHeight;
var width1=label.offsetWidth;
var position1=label.offsetHeight;
var position2=label.offsetTop;
var windowHeight = $wnd.innerHeight;
var scroll=$wnd.pageYOffset;
alert(scroll+"scroll");
var t=position-scroll;
var z=windowHeight-scroll;
var x="Totalheight"+screen.height;
var y=position1+position2+positionpop;
if(position1+position2+positionpop<windowHeight)
{
alert("no change");
}
if(position1+position2+positionpop>windowHeight )
{
popup.setAttribute("style","top:"+(position2-positionpop)+"px");
}
if(t<=0 || z<=0)
{
popup.setAttribute("style","bottom:"+(diff)+"px");
}
I have reached upto the dynamically changing the position up and down when the label is in the top but still have one problem that I both up and down position occured one by one I want to bound it into one..
if(position2+positionpop<windowHeight || t<=0)
{
popup.setAttribute("style","bottom:"+((windowHeight-(position2+position1))-positionpop)+"px");
}
else
{
if(position2+positionpop>windowHeight && t>0)
{
popup.setAttribute("style","top:"+(position2-positionpop)+"px");
}
}
You should use PopupPanel.setPopupPositionAndShow and PopupPanel.setPopupPosition. See the PopupPanel javadoc sample.
Related
This is my first post to Stack, appreciate the work you guys do, amazing.
I have a sap.m.table sap ui5 and i have 4 records
out of 4, 2 are selected by default, i want to disable the preselected once based on condition.
I have tried below code but its not working, any input please?
View
/results' }" **mode="MultiSelect"**
Controller logic
//--->disable the selected department checkboxes
var tbl = that.getView().byId('idImpactTable');
var header = tbl.$().find('thead');
var selectAllCb = header.find('.sapMCb');
selectAllCb.remove();
tbl.getItems().forEach(function(r) {
var obj = r.getBindingContext("impactModel").getObject();
var oStatus = obj.COMPLETED;
var cb = r.$().find('.sapMCb');
var oCb = sap.ui.getCore().byId(cb.attr('id'));
if (oStatus === "X") {
oCb.setSelected(true);
oCb.setEnabled(false);
} else {
oCb.setEnabled(false);
}
});
Multiselect Mode Table - Make selected check box read only
Last time I tried this I found it easiest to use the updateFinished event on the table, and then use an internal property of the column list item, like so:
onTableUpdateFinished: function (oEvent) {
oEvent.getSource().getItems().forEach(function (item) {
var data = item.getBindingContext().getObject();
item._oMultiSelectControl.setEnabled(!data.IsEnabled); //whatever your check is
});
}
You'll have to find a way to keep them disabled though when using the Select All checkbox at the top of the table. I ended up extending sap.m.Table to accomplish that, there might be easier ways...
My extension is like this
sap.ui.define([
"sap/m/Table"
], function(Control) {
return Control.extend("myapp.controls.MyTable", {
updateSelectAllCheckbox: function(oEvent) {
if (this._selectAllCheckBox && this.getMode() === "MultiSelect") {
var aItems = this.getItems();
var iSelectedItemCount = this.getSelectedItems().length;
var iSelectableItemCount = aItems.filter(function(oItem) {
//standard table does not check if the item is enabled
return oItem.getSelected() || oItem._oMultiSelectControl.getEnabled();
}).length;
// set state of the checkbox by comparing item length and selected item length
this._selectAllCheckBox.setSelected(aItems.length > 0 && iSelectedItemCount === iSelectableItemCount);
}
}
});
});
And just the standard renderer
sap.ui.define([
"sap/m/TableRenderer"
], function(Control) {
return Control.extend("myapp.controls.MyTableRenderer", {
});
});
I suppose I could have extended the ColumnListItem but that was more effort than I wanted to put into the table extension
I have managed to find the solution, please find sample code to achieve.
//--->disable the selected department checkboxes
var tbl = that.getView().byId("idImpactTable");
var header = tbl.$().find("thead");
var selectAllCb = header.find(".sapMCb");
selectAllCb.remove();
var aItems = that.byId("idImpactTable").getItems();
//---> Check individual item property value and select the item
aItems.forEach(function(oItem) {
debugger;
//---> If using OData Model items Binding, get the item object
var mObject = oItem.getBindingContext().getObject();
var sPath = oItem.getBindingContextPath();
var completed = oItem.oBindingContexts.impactModel.getProperty("COMPLETED");
//--->get the id of Multi Checkbox
var cb = oItem.$().find(".sapMCb");
var oCb = sap.ui.getCore().byId(cb.attr("id"));
if (completed === "X") {
oCb.setEditable(false);
oItem.setSelected(true);
oItem.getCells()[4].setEnabled(false);
} else {
oItem.setSelected(false);
}
});
Thank you,
Jacob.Kata
//--->disable the selected department checkboxes
var tbl = that.getView().byId('idImpactTable');
tbl.getItems().forEach(function(r) {
// this makes the trick --->
var oMultiSelCtrl = r.getMultiSelectControl();
oMultiSelCtrl.setDisplayOnly( true );
});
When I hover on pie chart, the values are displayed in tooltip. However, I want to display values outside of pie chart. I want to make chart like this image:
How to do this?
I was able to get something similar working using chart.js v2.3.0 using both the plugin API and extending chart types API. You should be able to take this as a starting point and tweak it to your needs.
Here is how it looks after being rendered.
Note, this requires digging deep into chart.js internals and could break if they change the way tooltips are positioned or rendered in the future. I also added a new configuration option called showAllTooltips to enable selectively using the plugin on certain charts. This should work for all chart types, but I am currently only using it for pie, doughnut, bar, and line charts so far.
With that said, here is a working solution for the image above.
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create a namespace to persist plugin state (which unfortunately we have to do)
if (!chart.showAllTooltipsPlugin) {
chart.showAllTooltipsPlugin = {};
}
// turn off normal tooltips in case it was also enabled (which is the global default)
chart.options.tooltips.enabled = false;
// we can't use the chart tooltip because there is only one tooltip per chart which gets
// re-positioned via animation steps.....so let's create a place to hold our tooltips
chart.showAllTooltipsPlugin.tooltipsCollection = [];
// create a tooltip for each plot on the chart
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
// but only create one for pie and doughnut charts if the plot is large enough to even see
if (!_.contains(['doughnut', 'pie'], sector._chart.config.type) || sector._model.circumference > 0.1) {
var tooltip;
// create a new tooltip based upon configuration
if (chart.config.options.showAllTooltips.extendOut) {
// this tooltip reverses the location of the carets from the default
tooltip = new Chart.TooltipReversed({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
} else {
tooltip = new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart);
}
// might as well initialize this now...it would be a waste to do it once we are looping over our tooltips
tooltip.initialize();
// save the tooltips so they can be rendered later
chart.showAllTooltipsPlugin.tooltipsCollection.push(tooltip);
}
});
});
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we want to wait until everything on the chart has been rendered before showing the
// tooltips for the first time...otherwise it looks weird
if (!chart.showAllTooltipsPlugin.initialRenderComplete) {
// still animating until easing === 1
if (easing !== 1) {
return;
}
// animation is complete, let's remember that fact
chart.showAllTooltipsPlugin.initialRenderComplete = true;
}
// at this point the chart has been fully rendered for the first time so start rendering tooltips
Chart.helpers.each(chart.showAllTooltipsPlugin.tooltipsCollection, function (tooltip) {
// create a namespace to persist plugin state within this tooltip (which unfortunately we have to do)
if (!tooltip.showAllTooltipsPlugin) {
tooltip.showAllTooltipsPlugin = {};
}
// re-enable this tooltip otherise it won't be drawn (remember we disabled all tooltips in beforeRender)
tooltip._options.enabled = true;
// perform standard tooltip setup (which determines it's alignment and x, y coordinates)
tooltip.update(); // determines alignment/position and stores in _view
tooltip.pivot(); // we don't actually need this since we are not animating tooltips, but let's be consistent
tooltip.transition(easing).draw(); // render and animate the tooltip
// disable this tooltip in case something else tries to do something with it later
tooltip._options.enabled = false;
});
}
},
});
// A 'reversed' tooltip places the caret on the opposite side from the current default.
// In order to do this we just need to change the 'alignment' logic
Chart.TooltipReversed = Chart.Tooltip.extend({
// Note: tooltipSize is the size of the box (not including the caret)
determineAlignment: function(tooltipSize) {
var me = this;
var model = me._model;
var chart = me._chart;
var chartArea = me._chartInstance.chartArea;
// set caret position to top or bottom if tooltip y position will extend outsite the chart top/bottom
if (model.y < tooltipSize.height) {
model.yAlign = 'top';
} else if (model.y > (chart.height - tooltipSize.height)) {
model.yAlign = 'bottom';
}
var leftAlign, rightAlign; // functions to determine left, right alignment
var overflowLeft, overflowRight; // functions to determine if left/right alignment causes tooltip to go outside chart
var yAlign; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (model.yAlign === 'center') {
leftAlign = function(x) {
return x >= midX;
};
rightAlign = function(x) {
return x < midX;
};
} else {
leftAlign = function(x) {
return x <= (tooltipSize.width / 2);
};
rightAlign = function(x) {
return x >= (chart.width - (tooltipSize.width / 2));
};
}
overflowLeft = function(x) {
return x - tooltipSize.width < 0;
};
overflowRight = function(x) {
return x + tooltipSize.width > chart.width;
};
yAlign = function(y) {
return y <= midY ? 'bottom' : 'top';
};
if (leftAlign(model.x)) {
model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (overflowLeft(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
} else if (rightAlign(model.x)) {
model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (overflowRight(model.x)) {
model.xAlign = 'center';
model.yAlign = yAlign(model.y);
}
}
}
});
I want to have the drag'n'drop functionality on some labels that are positioned with a absolute layout in a nativescript app. Is it even possible to move them in a new absolute position using drag'n'drop? If yes, can you explain a way to achieve this?
Thank you in advance.
After a little research I found out that you can achieve this with the following steps:
Define an Absolute Layout
Inside it place a label
On the label observer the pan gesture
using the deltaX and deltaY you can change the left and top values of the label using the static method setLeft() and setTop() of absolute layout on the label.
Sample xml:
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
<AbsoluteLayout>
<Label left="10" top="10" text="drag me" id="dragLabel" />
</AbsoluteLayout>
</Page>
Sample js code:
var viewModule = require("ui/core/view");
var gestures = require("ui/gestures");
var absoluteLayout = require("ui/layouts/absolute-layout");
function pageLoaded(args) {
var page = args.object;
var dragLabel = viewModule.getViewById(page, "dragLabel");
var observer = dragLabel.observe(gestures.GestureTypes.pan, function (panGestureEventData) {
var deltaX = panGestureEventData.deltaX;
var deltaY = panGestureEventData.deltaY;
absoluteLayout.AbsoluteLayout.setTop(this, deltaY);
absoluteLayout.AbsoluteLayout.setLeft(this, deltaX);
}, dragLabel);
};
Also, nativescript in the current version (1.2.x) doesn't support the state in the gestures. In the pan gesture, the state is really necessary to know. Here is what you can do (in ios), so you can get the state. Edit the file /tns_modules/ui/gestures/gestures.ios.js and change the function _getPanData with the following:
function _getPanData(args, view) {
var recognizer = args.ios;
var state = "unknown";
switch(recognizer.state) {
case UIGestureRecognizerStateBegan:
state = "began";
break;
case UIGestureRecognizerStateChanged:
state = "changed";
break;
case UIGestureRecognizerStateEnded:
state = "ended";
break;
case UIGestureRecognizerStateCancelled:
state = "cancelled";
break;
case UIGestureRecognizerStateFailed:
state = "failed";
break;
}
return {
type: args.type,
view: args.view,
ios: args.ios,
android: undefined,
deltaX: recognizer.translationInView(view).x,
deltaY: recognizer.translationInView(view).y,
state: state
};
}
Then, you can access the state with the state field:
var observer = dragLabel.observe(gestures.GestureTypes.pan, function (panGestureEventData) {
// ... panGestureEventData.state has on of the above values...
});
I'm using Chart.js (doughnut chart) and I would like to ask if is there any choice to highlight area programmatically? I mean - when I click on a button, then the specific area will be highlighted.
Thanks for your reply.
Just loop through the doughnut segments, match based on label and swap / restore the fill color.
function highlight(label) {
myDoughnutChart.segments.forEach(function (segment, i) {
if (segment.label == label) {
if (segment.fillColor == segment.highlightColor)
segment.restore(["fillColor"]);
else
segment.fillColor = segment.highlightColor;
myDoughnutChart.render();
}
})
}
Fiddle - http://jsfiddle.net/35of1Lzg/
I've disabled tooltips and the tooltip highlight by setting tooltipEvents = [], but if you want them back you can always remove it from the options, but then hover / mouseout and the button click will do the same thing.
To popup the tooltip too when highlighting use this
function highlight(label) {
myDoughnutChart.segments.forEach(function (segment) {
if (segment.label == label) {
if (segment.fillColor == segment.highlightColor)
segment.restore(["fillColor"]);
else
segment.fillColor = segment.highlightColor;
myDoughnutChart.render()
}
})
var activeSegements = [];
myDoughnutChart.segments.forEach(function (segment) {
if (segment.fillColor === segment.highlightColor) {
activeSegements.push(segment)
}
});
myDoughnutChart.showTooltip(activeSegements, true)
}
http://jsfiddle.net/jdr5381e/
FYI the fiddles are no longer working, you'll need to replace the links to the Chart.min.js
I used these to get them working: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.1.1/Chart.js
As the title says, how to make the sap.m.ProgressIndicator not animated when changing the percent value of it?
I cannot find a method for it, and extending would probably be the way to go, but maybe somebody has already figured it out and done it?
My Google search was not successful though.
interesting question, below is the sap.m.ProgressIndication.prototype.setPercentValue function, you can see when the percent value changes the bars values is changed via an linear animation
My suggestion, the easiest way to change this behavior is to extend the control to your own control and to redefine the setPercentValue, either remove the animate function on the bar or set time to null so there is no animation
sap.m.ProgressIndicator.prototype.setPercentValue = function(fPercentValue) {
var that = this;
...
if (that.getPercentValue() != fPercentValue) {
// animation without rerendering
this.$().addClass("sapMPIAnimate");
var time = Math.abs(that.getPercentValue() - fPercentValue) * 20;
this.setProperty("percentValue", fPercentValue, true);
var $Bar = this.$("bar");
$Bar.animate({
width : fPercentValue + "%"
}, time, "linear", function() {
that._setText.apply(that);
that.$().removeClass("sapMPIAnimate");
});
}
something like
jQuery.sap.declare("my.ProgressIndicator");
jQuery.sap.require("sap.m.ProgressIndicator");
sap.m.ProgressIndicator.extend("my.ProgressIndicator", {
renderer: {}
});
my.ProgressIndicator.prototype.setPercentValue = function(fPercentValue) {
var that = this;
// validation of fPercentValue
if (typeof (fPercentValue) == "number") {
if (that.getPercentValue() != fPercentValue) {
// animation without rerendering
this.$().addClass("sapMPIAnimate");
//var time = Math.abs(that.getPercentValue() - fPercentValue) * 20;
var time = 0;
this.setProperty("percentValue", fPercentValue, true);
var $Bar = this.$("bar");
$Bar.animate({
width : fPercentValue + "%"
}, time, "linear", function() {
that._setText.apply(that);
that.$().removeClass("sapMPIAnimate");
});
}
return this;
};
There is no convenient method to suppress this behavior.
You can only extend the control and overwrite the method setPercentValue to you desired behavior.
As of UI5 1.73, the animation on percantageValue-change can be turned off by setting the property displayAnimation to false.
Determines whether a percentage change is displayed with animation.
Since: 1.73.
<ProgressIndicator displayAnimation="false" />