I am working on a Titanium Appcelerator project, a tabbed application with tables. These tables contain a gradient background with a label and an input field. The problem is that on iOS when the row is tapped in the label area, the background color of the row fades to black and then fades back in. This is an old app that I'm updating for the latest iOS devices and Titanium version. It didn't behave this way before, but I have no idea where the change might be. Here are some tidbits where these UI elements are created.
function createRow(obj){
var row;
if (Titanium.Platform.name == 'iPhone OS') {
obj.selectionStyle = Ti.UI.iPhone.TableViewCellSelectionStyle.NONE;
obj.height = 40;
obj.width = 200;
obj.touchEnabled = false;
row = Titanium.UI.createTableViewRow(obj);
} else if (Titanium.Platform.name == 'android'){
obj.touchEnabled = true;
obj.width = Titanium.Platform.displayCaps.platformWidth-8;
if(Titanium.Platform.displayCaps.platformWidth > 320){
obj.height= getAndroidNumbers(40,70);
} else {
obj.height= 40;
}
row = Titanium.UI.createView(obj);
var row2 = Titanium.UI.createView(obj);
row.add(row2);
row2.addEventListener('click',function(e){
Ti.UI.Android.hideSoftKeyboard();
});
row2.addEventListener('swipe',function(e){
Ti.UI.Android.hideSoftKeyboard();
});
row2.addEventListener('touchmove',function(e){
Ti.UI.Android.hideSoftKeyboard();
});
}
return row;
}
Any ideas would be greatly appreciated.
I think what you are talking about is the highlight option of the tableview.
on iPhone to set the highlight (or disable it) you would use the selectionStyle of the tableview. so to disable it you would do:
selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE
on Android try this:
tableView :{
backgroundColor:'transparent',
separatorStyle:'none',
selectionStyle:'none',
separatorColor : 'transparent',
}
Related
I'm building an expandable Composable which would be expanded when clicked.
This would be implemented by using the AnimatedVisibility which works perfectly.
Code for the visibility animation:
AnimatedVisibility(
visible = isExpanded,
) {
// Content removed.
}
The problem I'm currently facing is that this is located in a vertical scrollable column and it should scroll to the expanded content when clicked next to expanding it.
As I read this would be done by using the BringIntoViewRequester as in the code snippet below:
var isExpanded by remember { mutableStateOf(false) }
val intoViewRequester = remember { BringIntoViewRequester() }
ClickableComposable(modifier = Modifier.clickable {
isExpanded = !isExpanded
if(isExpanded) {
coroutineScope.launch {
// delay(200)
intoViewRequester.bringIntoView(rect = null)
}
}
})
AnimatedVisibility(
modifier = Modifier.bringIntoViewRequester(intoViewRequester),
visible = isExpanded,
) {
// Content removed.
}
The code above works with the delay but that's not a perfect interaction for the user. To first see the content expanding and afterwards see the page scroll. The ideal situation would be that it would happen at the same time, however the content is not yet measured in any way. By removing the delay it does not work as the content is not yet visible.
Is there anything in Compose to do the expanding and scrolling to at the same time?
After selecting the whole text in a TextField using TextSelection() it does indeed select the whole text but after pressing a key on the keyboard, it starts adding pressed letters/numbers to the start of the text as opposed to deleting the old one and replacing it with the newly typed letters/numbers.
Is this expected behavior? If so, is there any way I can programatically select the text and then replace it upon pressing a key on the keyboard?
This is how I select the text:
manualEditorNode.addListener(() {
if (manualEditorNode.hasFocus) {
manualInputController.selection = TextSelection(
baseOffset: 0, extentOffset: manualInputController.text.length);
}
});
The following works for me in my program. Maybe you can try something like this?
var cursorPos = textInputController.selection;
setState(() {
textInputController.text = newInput;
if (cursorPos.start > newInput.length) {
cursorPos = new TextSelection.fromPosition(
new TextPosition(offset: newInput.length));
}
textInputController.selection = cursorPos;
});
I'm trying to make angular ui-grid automatically resize the height so that all rows are shown without the need of its scrollbar, but without wasting space if there are only a couple rows in the grid. Someone has asked a similar question (Angular ui-grid dynamically calculate height of the grid), but the question presupposes that the row heights are constant. If the row heights are different (for example, because you have word-wrap enabled), then the accepted solution to the problem (https://stackoverflow.com/a/28706349/877570) won't work, because the solution as does the question assumes constant row height. If I have a cell with a large amount of text in it, and the text wraps to the next line, then that rows height is different.
I found a possible solution by the user anhkind here: (https://github.com/angular-ui/ui-grid/issues/1735)
.ui-grid, .ui-grid-viewport {
height: auto !important;
}
"And of course minRowsToShow and virtualizationThreshold should be set to the size of the list."
However, when I deploy his solution, it takes a much longer time for the grid to render.
Does anyone know how to address this or have an alternative solution?
$scope._minRows = 10;
$scope._maxRows = 10;
// Lots of Grid Options, plus data setting going on here.
$scope.agendaItemsGridOptions.onRegisterApi = function(gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
});
var setMinRowsLogic = function() {
$scope.gridApi.grid.options.minRowsToShow = $scope._minRows;
if (!_.isUndefined($scope.agendaItemsGridOptions.data)) {
var len = $scope.agendaItemsGridOptions.data.length;
if (len > $scope._maxRows) {
$scope.gridApi.grid.options.minRowsToShow = $scope._maxRows;
} else
if (len < $scope._minRows) {
$scope.gridApi.grid.options.minRowsToShow = $scope._minRows;
} else {
$scope.gridApi.grid.options.minRowsToShow = len;
}
}
};
I am using Highcharts and I am trying to make the legend to disappear and appear using a button, to save some screen real-estate.
I tried everything I could think of and all I managed to do is to make the SVG of the legend to hide and show using chart.legend.[group, nav, container].hide() but the white space which the legend takes never goes away. I even tried deleting the legend DOM element but the chart wouldn't resize (even calls to chart.reflow() don't help.
See here: http://jsfiddle.net/zbzzn/q83h5g4z/1/
Is there any way to make the legend disappear and reflow the chart so that the legend white space goes away?
Here's my sketch for a toggle method that sits directly on the Legend prototype. It avoids modifying the container width and height.
Highcharts.Legend.prototype.toggle = function () {
if (this.display) {
this.group.hide();
} else {
this.group.show();
}
this.display = !this.display;
this.chart.isDirtyBox = true;
this.chart.redraw();
};
Live demo at http://jsfiddle.net/highcharts/3Bh7b/76/
I managed to do a hack around it that works:
http://jsfiddle.net/q83h5g4z/4/
I really hope there is another way to do it without the hack.
if (!isVisible) {
originalLegendHeight = legend.legendHeight;
legend.options.maxHeight = -1; //0 doesn't work :( because someone did "if (maxHeight)" instead of "if (maxHeight === null)"
$('#container').height($('#container').height()-legend.legendHeight);
chart.redraw();
chart.reflow();
} else {
legend.options.maxHeight = null;
$('#container').height($('#container').height()+originalLegendHeight);
chart.redraw();
chart.reflow();
}
See this solution:
http://jsfiddle.net/3Bh7b/73/
var legend = chart.legend;
if(legend.display) {
legend.group.hide();
legend.display = false;
} else {
legend.group.show();
legend.display = true;
}
The final solution I reached is (where legendVisible determines the visibility of the legend) :
var legendElement = $(chart.container).find('.highcharts-legend');
if (legendElement.length > 0) {
if (chart.legend.options.enabled && legendVisible) {
legendElement.show();
chart.legend.options.maxHeight = chart.legend.options.originalMaxHeight || null;
chart.reflow();
} else {
legendElement.hide();
chart.legend.options.originalMaxHeight = chart.legend.options.maxHeight;
chart.legend.options.maxHeight = -1;
chart.reflow();
}
}
I have an unordered 'source' list that can contain up to around 1,000 list items. I want to be able to drag the items from the source list into a connected 'destination' list. I have everything working great until my source list gets filtered. I'm using the jquery quicksearch plugin to filter (search) my source list. The filter is accomplished by setting 'display:none;' on items that don't match the search.
When 1..n items in my source list are hidden, the drag operation is not fluid when initiated. Meaning, I click on the item I want to drag, move my mouse around the screen, but the item I'm dragging does not appear under my cursor until about a full second after I've initiated the drag.
For diagnosis, I've slimmed down my use case to just one list that I want to sort. I've completely eliminated the use of quicksearch by just hard coding half of my list items as hidden. I'm still able to reproduce the 'non-fluid' behavior. My example is here:
http://pastebin.com/g0mVE6sc
If I remove the overflow style from the list in my example, the performance is a little better, but still slower than I'd hope to see.
Does anyone have any suggestions for me before I start considering other options?
Thanks in advance.
As you can see on this jsferf example, calculating outerWidth()/outerHeight() (this is what the plugin does - see below) for hidden elements (with display none) is terribly slower than for visible elements, wether it is achieved by a style attribute or a class.
The only way I have found to bypass this and still achieve the same result is to set the height for the elements to hide to zero, instead of working with the display property, whether using the style atttibute or a class:
<li style="height: 0;">b</li>
<li class="hidden">b</li>
.hidden { height: 0 }
DEMO (with class) - DEMO (with style attr)
What's happenning with sortable when dragging an element ?
When starting dragging, the plugin refreshes the list of all items and recalculates positions of all elements. The plugin actually gets outerWidth and outerHeight:
_mouseStart: function(event, overrideHandle, noActivation) {
...
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
this.refreshPositions();
...
}
refreshPositions: function(fast) {
...
for (var i = this.items.length - 1; i >= 0; i--) {
var item = this.items[i];
...
if (!fast) {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
...
return this;
},
If you still want to use display:none, this is a simple fix to the jQuery UI source specified in Didier's answer:
if (!fast) {
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
}
else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
}
This is my very first post on stackoverflow, so do let me know if I messed something up.
I was also having a similar problem, but with hidden drop containers instead of sortable items. Here is my solution applying Jordan's answer to both sortable items and their containers and simply replacing the relvent method.
$.ui.sortable.prototype.refreshPositions = function(fast) {
//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
if(this.offsetParent && this.helper) {
this.offset.parent = this._getParentOffset();
}
for (var i = this.items.length - 1; i >= 0; i--){
var item = this.items[i];
//We ignore calculating positions of all connected containers when we're not over them
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
continue;
var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
if (!fast) {
/********** MODIFICATION ***********/
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
} else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
/********** END MODIFICATION ***********/
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
if(this.options.custom && this.options.custom.refreshContainers) {
this.options.custom.refreshContainers.call(this);
} else {
for (var i = this.containers.length - 1; i >= 0; i--){
/********** MODIFICATION ***********/
if (this.containers[i].element.css('display') == 'none') {
this.containers[i].containerCache.left = 0;
this.containers[i].containerCache.top = 0;
this.containers[i].containerCache.width = 0;
this.containers[i].containerCache.height = 0;
} else {
var p = this.containers[i].element.offset();
this.containers[i].containerCache.left = p.left;
this.containers[i].containerCache.top = p.top;
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
}
/********** END MODIFICATION ***********/
};
}
return this;
};
I came across with the same problem...
I've searched for a solution, but it seems there is no solution to the jquery problem, only some workaround...
I didn't found either a solution, just another workaround.
In my case I just created a general method to to a search in a sortable list, where on keyup, the code goes and do a find on every element in the list and was hiding it by fadeout if didn't match the value.
This was working very well, but when you have hundreds of items in a list, the of hidden gets big enough to trigger the slow effect on the drag&drop.
My solution was to reorder the list, bringing to the top the matched items..
Just remove and appendTo again...
This way I don't have problems with the hidden elements :)
Sorry this was no solution, but just another workaround..
Regards
More recently I came accross with this issue again... and found that my workaround was not the best solution anymore. Since the issue is the height... I've just create a CSS class with
.hidden {display: block; line-height:0; height: 0; overflow: hidden; padding: 0; margin: 0; }
and instead of setting the element hidden with just add this class and remove it to show/hide the element..
Regards,
AP
I got the same issue today with sortable + draggable table rows.
The solution was simple : use visibility:collapse instead of display:none and removing the jQuery hide/show function for the hidden lines did the trick. It's a lot faster now.
Hope I will help.