Attempting to clear tableView just doubles the content - ios

I am attempting to update my table view with updated data but whenever I try to clear it using either
tagsTable.setData();
or
tagsTable.setData([]);
or
tagsTable.data = null;
and then re-apply the updated data using
tagsTable.setData(TagsData);
It never clears the table originally so the new data is just added to the end of the table, so I have the old data as well as the new data in the 1 table.
Any one know whats wrong or how to fix it?

Here's a simple (classic Titanium) app that shows clearing and re-filling the table's data property via some buttons. I'd triple-check the validity of your TagsData sections/rows to make sure everything within the array is being set properly.
var
win = Ti.UI.createWindow({
title: "Table Funs",
layout: "vertical",
backgroundColor: "#ffffff"
}),
navwin = Ti.UI.iOS.createNavigationWindow({
window: win
}),
table = Ti.UI.createTableView(),
clearButton = Ti.UI.createButton({
title: "Clear Table",
width: Ti.UI.FILL,
height: 44,
backgroundColor: "#f4f4f4",
color: "red",
bottom: 1
}),
fillButton = Ti.UI.createButton({
title: "Fill Table",
width: Ti.UI.FILL,
height: 44,
backgroundColor: "#f4f4f4",
color: "blue",
bottom: 1
}),
tableData = [];
// Fill up tableData array with rows
tableData.push(Ti.UI.createTableViewRow({ title: "Hey" }));
tableData.push(Ti.UI.createTableViewRow({ title: "this" }));
tableData.push(Ti.UI.createTableViewRow({ title: "is" }));
tableData.push(Ti.UI.createTableViewRow({ title: "a" }));
tableData.push(Ti.UI.createTableViewRow({ title: "table" }));
clearButton.addEventListener("click", function() {
Ti.API.debug("Clicked clear button.");
table.setData(null);
return;
});
fillButton.addEventListener("click", function() {
Ti.API.debug("Clicked fill button.");
table.setData(tableData);
return;
});
// Fill table with our data
table.setData(tableData);
// Build window
win.add(clearButton);
win.add(fillButton);
win.add(table);
navwin.open();

Related

Keep 2 columns next to each other in PDFMake?

I want to have a text s.calculatedQuantity and next to it an icon. But i want them to be always next to each other and not be separated. Sometimes when s.setDescription is long i have a bad result like in the image below. And i dont know why there is sometimes that space between the icon and the text s.calculatedQuantity. Can someone explain to me that ?
.
I Have my code like this :
function generateSetDescription(s, picto) {
return {
columns: [
{
text: `${s.setDescription} - `,
fillColor: '#000',
color: '#FFF'
},
{
text: `${s.calculatedQuantity}`,
fillColor: '#000',
color: '#FFF'
},
{
image: icon,
width: 10,
height: 10,
fillColor: '#000',
},
]
}
}
The problem you're having seems to be caused by too long words (not text) normal text seems to wrap correctly when a blank space is found.
My suggestion is to programmatically break your 'very long words' adding a - in between.
something like this should work in your case
const text = veryLongTextWithLongWords;
const wrappedText = text.split(' ').map(word => {
if(word.length > 80){
return `${word.substr(0, 40)}-${word.substr(41)}
}
return word;
})
const columns = [
{ text: wrappedText }
]
You can test it out here
http://pdfmake.org/playground.html

Fit a wider table into PDF

This is in continuation to the question asked in github, Fit a wider table into PDF #261.
I'm reusing the same method(doc.autoTable) to create PDF out of different HTML inputs.
So, If I define the column style of 0th column as columnWidth: 'wrap', then the same style will be applied for all the HTML tables that invoke this particular method.
I'm not sure If I can follow long text example, as both the column names & table body are coming from HTML page directly. Whereas in the long text example, I'm seeing the column names being declared/defined as shown below
var columnsLong = getColumns().concat([
{title: "Title with\nlinebreak", dataKey: "text2"},
{title: "Long text column", dataKey: "text"},
]);
Now there are 2 questions.
1. I dont want to apply 'WRAP' for all the columns, as the table gets cut.
2. Need to apply 'wrap' for certain columns alone by mentioning the column name that comes from HTML/GSP page.
This is my code
var res = doc.autoTableHtmlToJson($(".printReportsCaveat")[0]);
doc.autoTable(res.columns, res.data, {
columnStyles : {'Plant':{columnWidth: 'wrap'},
'Mine':{columnWidth: 'wrap'},
0:{textColor: [0,105,170]}
},
margin: {top: 55, bottom : 110},
headerStyles: {
overflow: 'linebreak',
// columnWidth: 'auto',
halign: 'center'
},
styles : {
overflow: 'linebreak',
halign: 'center',
fontSize: 8
},
createdCell: function(cell, data) {
var group = $('#groupByValue').val();
addColorToCell(group, level3Flag, level2Flag, data, cell);
},
addPageContent : function(data) {
printHeadNFoot(doc, userDtl, data);
},
drawCell: function(cell, data) {
designCell(data,doc);   
},
});
Kindly help!
If I understand your issue correctly you can try referencing a specific column by index instead of by key. I.e. columnWidth: {0: columnWidth: 'wrap'}.

Sproutcore SC.MenuPane keep/remember/visible selected item

I have a working popup button with menu 2 options, and need to 'keep/remember' the selected item visible to the user, in other words, the next time the menu pops up, the previous made choice should be visible (eg highlighted).
selectMenuButton: SC.PopupButtonView.extend({
layout: {left:10, bottom: 10, height: 18, width:100},
controlSize: SC.SMALL_CONTROL_SIZE,
title: 'Menu',
menu: SC.MenuPane.extend({
layout: { width: 150 },
items: [
{ title: 'option1', checkbox: YES, action: 'action1',target: 'App.Controller1'},
{ title: 'option2', checkbox: NO, action: 'action2',target: 'App.Controller2'}
]
}),
}),
I tried classnames css .active or .sel, but that didn't work.
Please some advice, thanks in advance.

OpenLayers 3 select style

In OL2 I was able to specify a "select" style in the style definition. In OL3 this doesn't seem to exist. If I understand it correctly, I can set a style for the select interaction. However, this likely won't work in my case since every layer has a unique "selected" style. Am I mistaken in my assessment of the capability? Is there another/optimal way to do this in OL3?
Let's assume that you have a style parameter stored in each ol.Feature, you can add a ol.style.StyleFunction to your ol.interaction.Select and return a style based on this parameter. Like so:
var styles = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,
color: [237, 212, 0, 0.8]
})
}),
'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'pin.png'
})
}),
'geoMarker': new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
snapToPixel: false,
fill: new ol.style.Fill({color: 'black'}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
})
};
var select = new ol.interaction.Select({
style: function(feature, resolution) {
return [styles[feature.get('style_parameter')]];
}
});
And your feature would be like:
var geoMarker = new ol.Feature({
style_parameter: 'geoMarker',
geometry: new ol.geom.Point([0,0])
});
I know this a very old thread, but since I haven't been able to find a clear solution to this particular problem yet, I still deem it fit to post mine. Not sure how it holds up with a large number of layers and features, but this is the most elegant and concise solution I could come up with.
BTW: I'm using the latest version of OpenLayers, which at the moment is 6.3.1.
var map = new ol.Map({
...
layers: [
new ol.layer.Vector({
...
// Default style for layer1
style: default1,
// Hover style for layer1 (custom property)
hoverStyle: hover1,
// Selected style for layer1 (custom property)
selectedStyle: selected1
}),
new ol.layer.Vector({
...
// Default style for layer2
style: default2,
// Hover style for layer2 (custom property)
hoverStyle: hover2,
// Selected style for layer2 (custom property)
selectedStyle: selected2
})
],
...
});
var hoverInteraction = new ol.interaction.Select({
condition: ol.events.condition.pointerMove,
style: function(feature) {
var layer = hoverInteraction.getLayer(feature);
return layer.values_.hoverStyle;
}
});
map.addInteraction(hoverInteraction);
var selectInteraction = new ol.interaction.Select({
condition: ol.events.condition.click,
style: function(feature) {
var layer = selectInteraction.getLayer(feature);
return layer.values_.selectedStyle;
}
});

Function in Appcelerator causing issues when called quickly

I'm having a few issues with the last couple of pieces on my iOS app built with Appcelerator Titanium.
The app sample below shows one of my windows which allows the user to tap a view (which contains a word), which flips around to show the same word in a different language. The user can then tap the same view again and it animates back to the original position showing the original word.
When the user wants to move onto another word, they simple swipe on the view and it brings in the next word.
Here are the issues i'm experiencing;
If a user swipes super fast through loads of words, then taps to flip, it crashes.
If a user taps the view to flip the view around sometimes the second word flashes up before the animation takes place, it should only be seen as the view comes around into view.
and
3) The user can opt to drop the word, which when tapped performs a database update and then reloads the function and brings a new word in. Great for the first time you use it, but on the 2nd, 3rd, 4th time, the alertbox pops up multiple times rather than once.
Now, I suspect I'm doing something wrong here, but I can't work it out, i've moved code around to make sure labels aren't displaying before they should, but it keeps happening.
Can anyone shed any light on 1 or all of my points? I'm about to lose my mind!
I'm using Titanium 3.20 for iOS
Many thanks
Simon
var win = Titanium.UI.currentWindow;
var selectedlanguage = Ti.App.Properties.getString('langSelect');
// detect height
if (Titanium.Platform.displayCaps.platformHeight == 480) {
var MVTOP = 115;
var tapTOP = 83;
var swipeTOP = 275;
} else {
var MVTOP = 165;
var tapTOP = 133;
var swipeTOP = 325;
}
var masterView = Ti.UI.createView({
backgroundColor: '#FFF',
top: MVTOP,
width: 300,
height: 140,
opacity: 0.7
});
var state = true;
win.add(masterView);
var front = Ti.UI.createView({
backgroundColor: '#FFF',
top: 0,
left: 0,
width: 300,
height: 140,
opacity: 1.0,
touchEnabled: false
});
var back = Titanium.UI.createView({
backgroundColor: '#FFF',
top: 0,
left: 0,
width: 300,
height: 140,
opacity: 1.0,
touchEnabled: false
});
if (win.section == 'word_expressions') {
var label1 = Ti.UI.createLabel({
//text: verb_german,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 20
},
top: 50
});
var label2 = Ti.UI.createLabel({
//text: verb_english,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 20
},
top: 50
});
} else {
var label1 = Ti.UI.createLabel({
//text: verb_german,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 30
},
top: 50
});
var label2 = Ti.UI.createLabel({
//text: verb_english,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 30
},
top: 50
});
}
var dropButton = Ti.UI.createButton({
width: 120,
height: 41,
right: 15,
bottom: 15,
title: 'drop word',
backgroundColor: '#fd0100',
color: '#FFF',
font: {
fontSize: 15
},
opacity: 1.0
});
win.add(dropButton);
function loadWords() {
// get the section to query for the database
var wordSection = win.section;
// get a random pair of words
var db = Ti.Database.open('germanV6');
var rows = db.execute('SELECT * FROM Words WHERE ' + wordSection + ' = 1 AND word_dropped = 0 ORDER BY RANDOM() LIMIT 1');
var x = 0;
while (rows.isValidRow()) {
if (selectedlanguage == 'en') {
var word_1 = rows.fieldByName('word_english');
var word_2 = rows.fieldByName('word_german');
} else if (selectedlanguage == 'de') {
var word_2 = rows.fieldByName('word_english');
var word_1 = rows.fieldByName('word_german');
}
var word_id = rows.fieldByName('word_id');
rows.next();
}
// close database
rows.close();
var state = true;
label1.text = word_1;
front.add(label1);
masterView.add(front);
label2.text = word_2;
back.add(label2);
masterView.addEventListener('click', function (e) {
switch (state) {
case true:
Ti.API.info('true');
masterView.animate({
view: back,
transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT
});
break;
case false:
Ti.API.info('false');
label1.text = word_1;
masterView.animate({
view: front,
transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_RIGHT
});
break;
}
state = !state;
});
var eventListener = function () {
// update the DB to tell it the word has been dropped
var dbDelete = Ti.Database.open('germanV6');
var rowsDelete = dbDelete.execute('UPDATE Words SET word_dropped=1 WHERE word_id=' + word_id);
// pop an alert to notify the user the word has been dropped
var alertDialog = Titanium.UI.createAlertDialog({
title: 'Word Dropped',
message: 'This word has been dropped!' + word_id,
buttonNames: ['OK']
});
// show the message
alertDialog.show();
// load in a new word
//loadWords();
alertDialog.addEventListener('click', function (j) {
loadWords();
});
};
}
// fire the function and load our words into play
loadWords();
var tapLabel = Ti.UI.createLabel({
width: 200,
top: tapTOP,
text: 'tap to flip',
textAlign: 'center',
color: '#FFF',
font: {
fontSize: 15
}
});
var swipeLabel = Ti.UI.createLabel({
width: 320,
top: swipeTOP,
text: 'swipe for next word',
textAlign: 'center',
color: '#FFF',
font: {
fontSize: 15
}
});
win.add(tapLabel);
win.add(swipeLabel);
var grammarButton = Ti.UI.createButton({
width: 120,
height: 41,
left: 15,
bottom: 15,
title: 'verb tables',
backgroundColor: '#ffff01',
color: '#000',
font: {
fontSize: 15
},
opacity: 1.0
});
win.add(grammarButton);
swipeLabel.addEventListener('swipe', function (e) {
// reload the new word
loadWords();
});
masterView.addEventListener('swipe', function (e) {
// reload the new word
loadWords();
});
grammarButton.addEventListener('click', function (e) {
var newWin = Titanium.UI.createWindow({
url: 'verb_table.js',
backgroundImage: '/images/background_random.jpg',
backgroundColor: '#FFF',
barColor: '#000',
translucent: true,
color: '#FFF',
navTintColor: '#FFF',
titleControl: Ti.UI.createLabel({
text: 'Verb Table',
color: '#FFF'
}),
statusBarStyle: Titanium.UI.iPhone.StatusBar.LIGHT_CONTENT,
backButtonTitle: ''
});
newWin.nav = win.nav;
win.nav.openWindow(newWin, {
animated: true
});
});
loadWords() adds an event listener to masterView every time it is called. Probably the source of the crash. Do the Ti.API.info calls build up over time of using the app? I'd expect you should see it popping out 1 then 2 then 3... as it runs along.
Is there missing code? The eventListener function is defined, but I can't find where it is called. This function then has another listener that then calls loadWords again adding more listeners. the name of the function eventListener was difficult to look for because all the addEventListener references come up in a search because they match. I'd change the name of that function to something more distinct. It might be getting called in there, but I gave up looking for it.
There is something up with this code. I would expect that the var label1 and var label2 aren't the ones you are adding to the view later on, but I would expect them to go out of scope when they leave your blocks {}. I would move the var label1 and var label2 outside this if-else and just have label1 = Ti.UI... and the label2 = Ti.UI.. in there.
var label1;
var label2;
if (win.section == 'word_expressions') {
label1 = Ti.UI.createLabel({ // FIX
//text: verb_german,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 20
},
top: 50
});
label2 = Ti.UI.createLabel({ // FIX
//text: verb_english,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 20
},
top: 50
});
} else {
label1 = Ti.UI.createLabel({ // FIX
//text: verb_german,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 30
},
top: 50
});
label2 = Ti.UI.createLabel({ // FIX
//text: verb_english,
text: '',
textAlign: 'center',
color: '#000',
font: {
fontSize: 30
},
top: 50
});
}
front.add(label1);
back.add(label2);
Variable Scrope
http://msdn.microsoft.com/en-us/library/bzt2dkta(v=vs.94).aspx
I would say you need to rethink the loadWords function. It is perhaps doing way too much and the source of all the issues. The masterView.addEventListener should be moved out. The alertDialog should be setup a different way as well. Perhaps moving that code to generate the alert outside of the omni function loadWords.
The database is opened repeatedly inside loadWords, but never closed. You did close the row, but forgot the db.
front.add and back.add aren't necessary in the loadWords function, you should have these after the If-Else statement where you are defining them. Keep the code in there that updates, their .text properties.
Looking closer at the label definitions you are defining them exactly the same aside from the font size. I would fix that to only change the font inside the IF-ELSE.
Fix the place where you detect height as well. Move all the var [variable names] out of the block and define them once. In the IF-ELSE then assign them the correct values.

Resources