How to Add Read More/Read Less functionality
Use case
This package is great. It would be the only package one will need if it has read more / read less functionality. Since adding read more functionality is always likely to happen as far as rendering html text is concerned.
Proposal
I want to use this package to render html content on my flutter app. And some of my contents can be quite long. So, it will make sense to enable read more /read less functionality. Does this package have such functionality or any idea how to add such functionality to this package?
Thank you.
This is where a widget factory would help, where you listen to specific classes and put the content from them into an appropriate collapse widget.
Our accordion widget factory is doing something similar. The CustomCollapsible just shows the header and if not collapsed even the content. It's possible to show the content on tap:
class CustomWidgetFactory extends WidgetFactory {
@override
void parse(BuildMetadata meta) {
final dom.Element element = meta.element;
if (element.classes.contains('accordion-section')) {
Widget? header;
bool initialCollapsed = true;
meta.register(
BuildOp(
onChild: (collapseMeta) {
final dom.Element collapseElement = collapseMeta.element;
// ignore grand children etc.
if (collapseElement.parent != element) {
return;
}
if (element.classes.contains('accordion-header')) {
collapseMeta.register(
BuildOp(
onWidgets: (_, widgets) {
header = AbsorbPointer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: widgets.toList(),
),
);
return [];
},
),
);
}
if (element.classes.contains('accordion-content')) {
final String? styles = collapseMeta.element.attributes['style'];
if (styles != null) {
if (styles.contains(RegExp(r'display\s*?:\s*?block'))) {
initialCollapsed = false;
}
if (styles.contains(RegExp(r'display\s*?:\s*?none'))) {
initialCollapsed = true;
/// Remove display none from style attribute since otherwise the content is not displayed
_removeStyleAttribute(collapseMeta, r'display\s*?:\s*?none');
}
}
}
},
onWidgets: (_, widgets) => [
CustomCollapsible(
header: header ?? const SizedBox.shrink(),
initialCollapsed: initialCollapsed,
children: widgets.toList(),
)
],
),
);
}
return super.parse(meta);
}
/// Removes style attribute from meta attributes.
void _removeStyleAttribute(BuildMetadata meta, String styleAttribute) {
meta.element.attributes.update(
'style',
(value) => value.replaceAll(RegExp(styleAttribute), ''),
);
}
}
Html looks like this:
<div class="accordion-section">
<div class="accordion-header">
<a target="_self">Show or hide content</a>
</div>
<div class="accordion-content">
<p>Content</p>
</div>
</div>
Thanks for the response. However, this will not apply since the content is like news feed content (user generated content) which we display on our website written in ReactJs, on our mobile lite version written in React Native.
We cannot have the accordion class in the content to create the read more / read less functionality.