Skip to content

Commit ecf26dc

Browse files
authored
Merge pull request #4449 from albertgasset/MOBILE-4653-data
MOBILE-4653 data: Fix template rendering
2 parents 884a260 + de248a0 commit ecf26dc

File tree

2 files changed

+44
-38
lines changed

2 files changed

+44
-38
lines changed

src/addons/mod/data/services/data-helper.ts

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -217,49 +217,55 @@ export class AddonModDataHelperProvider {
217217
return '';
218218
}
219219

220-
// Replace the fields found on template.
221-
fields.forEach((field) => {
222-
let replace = `[[${field.name}]]`;
223-
replace = replace.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
224-
let replaceRegex = new RegExp(replace, 'gi');
225-
226-
const valuesInsideTags = new RegExp('>\\[\\[' + field.name + '\\]\\]<','gi');
227-
228-
if (template.match(valuesInsideTags)?.length) {
229-
// Replace field by a generic directive.
230-
const hasOffline = entry.hasOffline ? 'true' : 'false';
231-
232-
const render = `><addon-mod-data-field-plugin [field]="fields[${field.id}]" mode="${mode}" [database]="database" \
233-
[value]="entries[${entry.id}].contents[${field.id}]" [recordHasOffline]="${hasOffline}" \
234-
(gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin><`;
235-
236-
template = template
237-
.replace(valuesInsideTags, render)
238-
.replace(replaceRegex, entry.contents[field.id].content);
239-
} else {
240-
// Replace field by a generic directive.
241-
const render = `<addon-mod-data-field-plugin [field]="fields[${field.id}]" mode="${mode}" [database]="database" \
242-
[value]="entries[${entry.id}].contents[${field.id}]" [recordHasOffline]="${entry.hasOffline ? 'true' : 'false'}" \
243-
(gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin>`;
244-
245-
template = template.replace(replaceRegex, render);
246-
}
220+
const replaceAll = (text: string, pattern: string, replacement: string): string => {
221+
const escapedPattern = pattern.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
222+
223+
return text.replace(new RegExp(escapedPattern, 'gi'), replacement);
224+
};
247225

248-
// Replace the field name tag.
249-
replace = `[[${field.name}#name]]`;
250-
replace = replace.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
251-
replaceRegex = new RegExp(replace, 'gi');
226+
const replaceFields = (template: string, useRawContent: boolean): string => {
227+
fields.forEach((field) => {
228+
if (useRawContent) {
229+
// Replace field with unprocessed content.
230+
template = replaceAll(template, `[[${field.name}]]`, entry.contents[field.id]?.content ?? '');
231+
} else {
232+
// Replace field by a generic directive.
233+
const render = `<addon-mod-data-field-plugin [field]="fields[${field.id}]" mode="${mode}" \
234+
[database]="database" [value]="entries[${entry.id}].contents[${field.id}]" \
235+
[recordHasOffline]="${entry.hasOffline ? 'true' : 'false'}" \
236+
(gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin>`;
237+
template = replaceAll(template, `[[${field.name}]]`, render);
238+
}
252239

253-
template = template.replace(replaceRegex, field.name);
240+
// Replace the field name tag.
241+
template = replaceAll(template, `[[${field.name}#name]]`, field.name);
254242

255-
// Replace the field description tag.
256-
replace = `[[${field.name}#description]]`;
257-
replace = replace.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
258-
replaceRegex = new RegExp(replace, 'gi');
243+
// Replace the field description tag.
244+
template = replaceAll(template, `[[${field.name}#description]]`, field.description);
245+
});
259246

260-
template = template.replace(replaceRegex, field.description);
247+
return template;
248+
};
249+
250+
// First, replace fields inside attributes.
251+
// We can't use convertTextToHTMLElement because it removes elements that
252+
// are not allowed as a child of <div>, like <li> or <tr>.
253+
const templateElement = document.createElement('template');
254+
templateElement.innerHTML = template;
255+
templateElement.content.querySelectorAll('*').forEach((element) => {
256+
for (const name of element.getAttributeNames()) {
257+
const value = element.getAttribute(name) ?? '';
258+
if (value.match(/\[\[.*\]\]/)) {
259+
element.setAttribute(name, replaceFields(value, true));
260+
}
261+
}
261262
});
263+
template = templateElement.innerHTML;
264+
265+
// Replace fields inside elements.
266+
template = replaceFields(template, false);
262267

268+
// Replace actions.
263269
for (const action in actions) {
264270
const replaceRegex = new RegExp(`##${action}##`, 'gi');
265271
// Is enabled?

src/addons/mod/data/tests/behat/links.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Feature: Users can manage entries in database activities
3030
@javascript
3131
Scenario: Create links in list template
3232
Given I set the following fields to these values:
33-
| Repeated entry | <div class="colleague-entry-value mt-4"><span class="colleague-entry-value-title font-weight-bold">[[Email-Adresse#name]]</span><p><a href="mailto:[[Email-Adresse]]">[[Email-Adresse]]</a></p></div> |
33+
| Repeated entry | <div class="colleague-entry-value mt-4"><span class="colleague-entry-value-title font-weight-bold">[[Email-Adresse#name]]</span><p><a href="mailto:[[Email-Adresse]]">Mail: [[Email-Adresse]]</a></p></div> |
3434
And I click on "Save" "button" in the "sticky-footer" "region"
3535

3636
And I entered the data activity "Test database name" on course "Course 1" as "teacher1" in the app

0 commit comments

Comments
 (0)