My goal is it to create a search ListView with JSON Data.
This is working but I have a tiny problem with the search function.
When I type in a word, it has to be exactly the same word, which is in the Array of the ListView.
The main problem is that I have to type in the correct word.
For example: when the word stackoverflow is one item of the Array, I have to type in stackoverflow to find this item.
But I want to get the Item also when I type in stack or flow or stacko for example.
This is my code:
filterDatasource(event)
{
var searchString = event.nativeEvent.text.toLowerCase();
if (searchString != "")
{
var content = this.state.loadedContent;
var searchResultsArray = [];
for (var i = 0; i < content.length; i++) {
var detailArray = content[i];
const gattung = detailArray.Gattung;
const zugnummer = detailArray.Zugummer;
const ab = detailArray.ab;
const bis = detailArray.bis;
const wochentag = detailArray.Wochentag;
const zeitraum = detailArray.Zeitraum;
if (searchString.contains(ab.toLowerCase())) //searchString.indexOf(ab) >= 0
{
//alert('gefunden');
searchResultsArray.push(detailArray);
this.setState({ dataSource: ds.cloneWithRows(searchResultsArray) });
}
}
}
else {
this.setState({ dataSource: ds.cloneWithRows(this.state.loadedContent) });
}
},
You can do this with indexOf like this:
if (searchString.indexOf(ab.toLowerCase()) > -1)
{
...
}
Related
I want to loop through the data received from Firebase Realtime Database and for each piece of data, pass it through my ChatData model. However, when I try to pass in snapshot.value it says that The argument type 'Object?' can't be assigned to the parameter type 'Map<dynamic, dynamic>?'. How do I modify snapshot.value so that I can do this?
The code:
event.snapshot.children.forEach((snapshot) {
_dataList.add(snapshot.value);
msg = ChatData.fromJson(snapshot.value);
});
ChatData model:
ChatData.fromJson(Map<dynamic, dynamic>? json): //Transform JSON into Message
uid = json?['uid'] as String,
text = json?['text'] as String,
timestamp = DateTime.parse(json?['timestamp'] as String),
type = json?['type'] as String,
filterID = json?['filterID'] as String,
mumbleURL = json?['mumbleURL'] as String;
What I don't understand is that in another version of this code, I simply added each piece of data from the snapshot into a List and then iterated over this list index by index and it worked just fine. Putting into a List first allowed me to pass in each element into ChatData.fromJSON just fine...
event.snapshot.children.forEach((snapshot) {
_dataList.add(snapshot.value);
});
_dataList.forEach((element) {
msg = ChatData.fromJson(element); //This works just fine...why?
});
Change your ChatData Model like this.
ChatData.fromDocumentSnapshot(DocumentSnapshot jsonMap) {
try {
uid = jsonMap.get('uid') != null ? jsonMap.get('uid').toString() : '';
text = jsonMap.get('text') != null ? jsonMap.get('text').toString() : '';
timestamp = DateTime.parse(jsonMap.get('timestamp').toString());
type = jsonMap.get('type') != null ? jsonMap.get('type').toString() : '';
filterID = jsonMap.get('filterID') != null ? jsonMap.get('filterID').toString() : '';
mumbleURL = jsonMap.get('mumbleURL') != null ? jsonMap.get('mumbleURL').toString() : '';
} catch (e) {
uid = '';
text = '';;
type = '';
print(e);
}
}
and getChats like this.
Stream<List<ChatData>> getChats(Message message) {
return FirebaseFirestore.instance.collection("messages").doc(message.id).collection("chats").orderBy('time', descending: true).snapshots().map((QuerySnapshot query) {
List<ChatData> retVal = [];
query.docs.forEach((element) {
retVal.add(Chat.fromDocumentSnapshot(element));
});
return retVal;
});
}
Hope you will get an idea from this.
I have a custom class that fetches data from the database, that returns Future<List<Line>>, which lies in line_list.dart files :
Future<List<Line>> fetchingLinesData() async {
List<Line> lineList = [];
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'main.db');
Database database = await openDatabase(path, version: 1);
database.transaction((tnx) async {
dbRef.child('line').once().then((DataSnapshot dataSnapshot) async {
dataSnapshot.value.forEach((key, value) async {
List<Station> inLineStations = [];
for (var i = 0; i < 100; i++) {
if (value["station_$i"] != null) {
List<Map> stations = await tnx.rawQuery("SELECT * FROM Station");
stations.forEach((s) {
if (s['stationName'] == value["station_$i"]) {
Station stationInstance = Station(
key: s['key'],
cityName: s['cityName'],
stationName: s['stationName'],
stationLongitude: s['stationLongitude'],
stationLatitude: s['stationLatitude']);
inLineStations.add(stationInstance);
}
});
}
}
Line lineInstance = Line(
startStation: value['start_station'],
endStation: value['end_station'],
inLineStations: inLineStations,
notes: value['notes'],
price: value['price'],
transportationType: value['transportation_type']);
lineList.add(lineInstance);
});
});
});
return lineList;
}
}
and then in my main.dart widget, I have this :
List<Line> allLines = [];
I want to do something like this :
allLines = LinesList().fetchingLinesData();
But of course, it gives me an error as am trying to assign Future<List<Line>> to List<Line>
how to do it?
You have to await for future to complete.
allLines = await LinesList().fetchingLinesData();
You would just put the code below in a async function make main async and make your code
allLines = await LinesList().fetchingLinesData();
I'm trying to make an android app that use google sheet as my database. But when i input the data to google sheet it turns to 'undefined'. hope someone can help me to fix this
code that contains 'undefined'
function read_all_value(request){
var ss =SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var output = ContentService.createTextOutput(),
data = {};
//Note : here sheet is sheet name , don't get confuse with other operation
var sheet="sheet1";
data.records = readData_(ss, sheet);
var callback = request.parameters.callback;
if (callback === undefined) {
output.setContent(JSON.stringify(data));
} else {
output.setContent(callback + "(" + JSON.stringify(data) + ")");
}
output.setMimeType(ContentService.MimeType.JAVASCRIPT);
return output;
}
this code too
function readData_(ss, sheetname, properties) {
if (typeof properties == "undefined") {
properties = getHeaderRow_(ss, sheetname);
properties = properties.map(function(p) { return p.replace(/\s+/g, '_'); });
}
var rows = getDataRows_(ss, sheetname),
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
for (var p in properties) {
record[properties[p]] = row[p];
}
data.push(record);
}
return data;
}
function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
}
function getHeaderRow_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(1, 1, 1, sh.getLastColumn()).getValues()[0];
}
here is my google sheet
https://docs.google.com/spreadsheets/d/1qX61V-xw3IjK8L373iTqlaSN0cf3-eh3zrpDBYHr8JQ/edit?usp=sharing
Change readData_() function code below -
for (var p in properties) {
record[properties[p]] = row[p];
}
to this -
properties.forEach(function(key, i) {
record[key] = row[i];
});
I want to create a OList, so that every position opened a new OList if I tap on it. At this moment I have following code:
function readCustomerSuccessCallback(data, response) {
var citems = [];
for (var i = 0; i < data.results.length; i++) {
var citem = new sap.m.StandardListItem(
{
type: "Active",
tap : readProducts(data.results[i].STATION_ID),
title: data.results[i].CUSTOMER_NAME,
description: data.results[i].STATION_ID
});
citems.push(citem);
}
var oList = new sap.m.List({
headerText : "Customers",
setGrowingScrollToLoad: true,
items : citems,
press: function(e) {
console.log(oList.getSelectedItems());
}
});
oList.placeAt("content"); // place model onto UI
}
function readProducts(category) {
console.log("read request started");
startTime = new Date();
if (!haveAppId()) {
return;
}
sURL = myUrl;
var oHeaders = {};
oHeaders['Authorization'] = authStr;
//oHeaders['X-SMP-APPCID'] = appCID; //this header is provided by the logon plugin
var request = {
headers : oHeaders,
requestUri : sURL,
method : "GET"
};
OData.read(request, readProductsSuccessCallback, errorCallback);
}
The function read CustomerSuccesCAllback creates a OList,and if I tap on a field of this list, I want that a new List shows up. For the second step is the function readproducts responsible.
With this code it doesnt work. It shows me not the customers, but only theyre details.
Has anybody an idea?
Change in readCustomerSuccessCallback:
tap: function(e){
readProducts(this.getDescription),
}
//this will stop invoking the function while defining your items
While working with Titanium application, came across a situation where I want to change image of Spinner (i.e. Picker in Titanium)
Taking Picker's object I'm able to create spinner and manipulate data but not finding any mechanism which change the default image of spinner
Thinking to do like this replace-picker-with-button
any other idea?
You can directly change image of the spinner by its backgroundImage property.
For Example
backgroundImage: '/images/dropdown.png.
It will only work for Android and did not work with iPhone.
So if you want to make same UI for both Ios and Android then you can follow below trick.
Here is the global method which you can use to create and display Picker.
/*
pickerData: is the array of the values which you want to display in the picker
funName: is the callback function which will be called when user will select the row from picker. this function will have two parameters first will be selected row's text and second is the index of the selected row
title: is the title of the picker
index: is the default selected index in the picker
*/
function showPicker(pickerData, funName, title, index) {
if (title == undefined || title == "") {
title = "";
}
if (pickerData == undefined || pickerData == null) {
pickerData = [];
}
index = index || 0;
if (pickerData.length <= index || index < 0) {
index = 0;
}
var selectedCategory = pickerData[0];
var win = Ti.UI.createWindow({
backgroundColor : 'transparent',
});
//Check weather the Os is IOs or Android
//globals.isIos is the parameter which is indicating that current OS is IOs or not?
if (globals.isIos) {
var picker = Ti.UI.createPicker({
selectionIndicator : true,
bottom : 0,
width : '100%',
isSpinner : true,
});
data = [];
for (var p = 0; p < pickerData.length; p++) {
data.push(Ti.UI.createPickerRow({
title : pickerData[p],
index : p
}));
}
picker.add(data);
Ti.API.info("Tab Index" + index);
picker.setSelectedRow(0, index, true);
var selectedIndex = 0;
picker.addEventListener('change', function(e) {
selectedCategory = e.row.title;
selectedIndex = e.row.index;
});
//toolbar
var done = Titanium.UI.createButton({
title : 'Done',
style : Titanium.UI.iPhone.SystemButtonStyle.DONE,
});
done.addEventListener('click', function(e) {
funName(selectedCategory, selectedIndex);
win.close();
});
var title = Titanium.UI.createLabel({
text : title,
textAlign : 'left',
color : 'white',
font : {
fontWeight : 'bold',
fontSize : globals.isIpad ? 18 : "14dp"
}
});
var flexSpace = Titanium.UI.createButton({
systemButton : Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
});
var toolbar = Titanium.UI.iOS.createToolbar({
items : [title, flexSpace, done],
bottom : 216,
borderTop : true,
borderBottom : false,
barColor : '#3F3F3F'
});
win.addEventListener('click', function(e) {
win.close();
});
win.add(picker);
win.add(toolbar);
win.open();
} else {
var pickerView = Titanium.UI.createOptionDialog({
selectedIndex : index
});
pickerView.title = title;
data = [];
for (var p = 0; p < pickerData.length; p++) {
data.push(pickerData[p]);
};
pickerView.options = data;
pickerView.addEventListener('click', function(e) {
selectedCategory = pickerData[e.index >= 0 ? e.index : index];
funName(selectedCategory, e.index >= 0 ? e.index : index);
});
pickerView.show();
}
return win;
}
Now create one button or lable inside your window and set the dropdown image to its background.
So it will look like dropdown now handle click of the button and put below code in it.
var data = ["Android", "IOS", "Blackberry", "Windows"];
function callback(title, index) {
Ti.API.info('Selected title=' + title + ' index=' + index);
}
var defaultSelected = 1;
//Here functions is the global file in which my showPicker method is defined.
var pickerShow = functions.showPicker(data, callback, "Mobile OS", defaultSelected);
//Here globals is the file in which my isIos variable is defined.
if (globals.isIos) {
pickerShow.open();
}