I have this problem
I create app in Flutter and I am connected with my database (supabase). In my body table I have html text. Something like this:
<p>This is an example article. <span class="highlight" data-gallery-id="19">Click here</span> to see the gallery.</p>
Now I want to shop popup on my flutter screen when user click on Click here
My code – detail screen:
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:html/parser.dart' show parse;
class ArticleDetailScreen extends StatelessWidget {
final int articleId;
ArticleDetailScreen({required this.articleId});
final SupabaseClient supabase = Supabase.instance.client;
Future<Map<String, dynamic>> fetchArticleDetails() async {
try {
final response =
await supabase.from('articles').select().eq('id', articleId).single();
return response as Map<String, dynamic>;
} catch (error) {
print('Error fetching article details: $error');
return {};
}
}
Future<Map<String, dynamic>> fetchGalleryDetails(int galleryId) async {
try {
final response = await supabase
.from('galleries')
.select()
.eq('id', galleryId)
.single();
return response as Map<String, dynamic>;
} catch (error) {
print('Error fetching gallery details: $error');
return {};
}
}
Future<List<Map<String, dynamic>>> fetchGalleryImages(int galleryId) async {
try {
final response = await supabase
.from('articles_images')
.select()
.eq('gallery_id', galleryId);
return response as List<Map<String, dynamic>>;
} catch (error) {
print('Error fetching gallery images: $error');
return [];
}
}
Future<List<Map<String, dynamic>>> fetchSketchImages(int galleryId) async {
try {
final response = await supabase
.from('sketches_images')
.select()
.eq('gallery_id', galleryId);
return response as List<Map<String, dynamic>>;
} catch (error) {
print('Error fetching sketch images: $error');
return [];
}
}
void showGalleryPopup(BuildContext context, int galleryId) async {
final galleryDetails = await fetchGalleryDetails(galleryId);
final galleryImages = await fetchGalleryImages(galleryId);
final sketchImages = await fetchSketchImages(galleryId);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(galleryDetails['name'] ?? 'Gallery'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (galleryImages.isNotEmpty) ...[
Text('Zdjęcia'),
SizedBox(height: 10),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: galleryImages.map((image) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(image['image_url'],
width: 100, height: 100),
);
}).toList(),
),
),
],
if (sketchImages.isNotEmpty) ...[
Text('Szkice'),
SizedBox(height: 10),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: sketchImages.map((image) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(image['image_url'],
width: 100, height: 100),
);
}).toList(),
),
),
],
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Close'),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Article Details'),
),
body: FutureBuilder<Map<String, dynamic>>(
future: fetchArticleDetails(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text('Article not found.'));
} else {
final article = snapshot.data!;
final document = parse(article['body']);
document
.querySelectorAll('span[data-gallery-id]')
.forEach((element) {
final galleryId =
int.tryParse(element.attributes['data-gallery-id'] ?? '');
if (galleryId != null) {
element.attributes['onclick'] = 'flutter_gesture_detector';
element.classes.add('highlight');
}
});
return Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Html(
data: document.outerHtml,
style: {
".highlight": Style(
backgroundColor: Colors.greenAccent,
fontWeight: FontWeight.bold,
textDecoration: TextDecoration.underline,
),
},
onLinkTap:
(String? url, Map<String, String> attributes, element) {
if (attributes['onclick'] == 'flutter_gesture_detector') {
final galleryId =
int.tryParse(attributes['data-gallery-id']!);
if (galleryId != null) {
showGalleryPopup(context, galleryId);
}
}
},
),
),
);
}
},
),
);
}
}
When I click on Click here noting happen.
I dont know what to change or maybe you have another idea how to do it ?