Implement HTML <template> element

Please implement HTML ‘template’ element so I can stop using Custom Code’s with alpinejs.

Thanks

Russ

Thank you for the suggestion! As I see it if we had a template element it would behave exactly like custom code, so you would double click to edit its contents in the editor panel. Do you have suggestions on how it could be made more convenient for you?

Hi Martin

Ideally the same way that you’ve implemented <div>. A common pattern is to use Custom Codes like:

Custom Code containing <template x-if="status !== 'Running'">

some DOM

Custom Code containing </template>

It would be much easier to read the DOM and just see the <template>s with the x-* attributes directly.

You don’t need to have the template in the DOM so no need for custom code inside BSS

here is an example with a simple table

html

<div class="container">
	<div class="row">
			<div class="col">
					<div class="table-responsive">
							<table class="table" id="producttable">
								<thead>
									<tr>
										<th>UPS CODE</th>
										<th>Product Name</th>
									</tr>
								</thead>
								<tbody></tbody>
							</table>
					</div>
			</div>
	</div>
</div>

example with a data object
javascript

const data = [
  {
    upscode: '1235646565',
    product: 'Stuff',
  },
  {
    upscode: '0384928528',
    product: 'Acme Kidney Beans 2',
  },
];

function createTableRow(data) {
  const row = document.createElement('tr');
  const cell1 = document.createElement('td');
  const cell2 = document.createElement('td');
  cell1.textContent = data.upscode;
  cell2.textContent = data.product;
  row.appendChild(cell1);
  row.appendChild(cell2);
  return row;
}

function appendRowsToTableBody(tbody, rows) {
  rows.forEach((row) => tbody.appendChild(row));
}

const tbody = document.querySelector('tbody');
if (tbody) {
  if ('content' in document.createElement('template')) {
    const template = document.createElement('template');
    template.innerHTML = `<tr><td></td><td></td></tr>`;
    const rows = data.map((post) => {
      const clone = template.content.cloneNode(true);
      const cells = clone.querySelectorAll('td');
      cells[0].textContent = post.upscode;
      cells[1].textContent = post.product;
      return clone;
    });
    appendRowsToTableBody(tbody, rows);
  } else {
    const rows = data.map(createTableRow);
    appendRowsToTableBody(tbody, rows);
  }
} else {
  console.error('Table body not found');
}

example if fetching the data

javascript

async function fetchData(url) {
 try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return data;
 } catch (error) {
    console.error('There was a problem with the fetch operation:', error);
    return []; // Return an empty array or handle the error as needed
 }
}

fetchData('assets/js/data.json').then(fetchedData => {
 if (fetchedData.length > 0) {
    const tbody = document.querySelector('tbody');
    if (tbody) {
      if ('content' in document.createElement('template')) {
        const template = document.createElement('template');
        template.innerHTML = `<tr><td></td><td></td></tr>`;
        const rows = fetchedData.map(post => {
          const clone = template.content.cloneNode(true);
          const cells = clone.querySelectorAll('td');
          cells[0].textContent = post.upscode;
          cells[1].textContent = post.product;
          return clone;
        });
        appendRowsToTableBody(tbody, rows);
      } else {
        const rows = fetchedData.map(createTableRow);
        appendRowsToTableBody(tbody, rows);
      }
    } else {
      console.error('Table body not found');
    }
 } else {
    console.log('No data to display');
 }
}).catch(error => {
 console.error('Error fetching data:', error);
});

function createTableRow(data) {
 const row = document.createElement('tr');
 const cell1 = document.createElement('td');
 const cell2 = document.createElement('td');
 cell1.textContent = data.upscode;
 cell2.textContent = data.product;
 row.appendChild(cell1);
 row.appendChild(cell2);
 return row;
}

function appendRowsToTableBody(tbody, rows) {
 rows.forEach(row => tbody.appendChild(row));
}

Hi kuligaposten

Unless I’m missing something, I’m not sure how your answer relates to AlpineJS…?

@rm5170

I show you an example with a simple table
here is an example with alpineJs
look at the source code no <template> in the DOM

Thanks for your response.

‘x-for’ and ‘x-if’ needs to be declared on a template as per for — Alpine.js and if — Alpine.js

Currently the only way to do that is through Custom Codes I think.

Alpine.js is a great tool for css framework based on utilities or if you write all your css by yourself

Bootstrap is a component based framework and comes with javascript as well

Alpine.js x-if example

<div x-data="{ open: false }">
    <button @click="open = ! open">Expand</button>
    <template x-if="open">
	  <p>Content...</p>
    </template>
</div>

In Bootstrap Studio you drop a bootstrap collapse component which do the same thing

If you want a dropdown you drop a bootstrap dropdown component,
I don’t think you use an Alpine.js UI component for that

The same goes for other javascript components in bootstrap like

  • Accordion
  • Alerts
  • Carousel
  • Collapse
  • Dropdowns
  • Modal
  • Navbar
  • Nav & tabs
  • Offcanvas
  • Popover
  • Toast
  • Tooltips

you don’t use Alpine.js UI components for that, you use bootstrap components

Why are you using Alpine.js with Bootstrap?

if you had inspected the example you would have seen there is no custom code with a <template>
quite pointless to show you an example if you don’t look at it