javascripttemplatingalpine.js

Manage javascript templates effectively


I am not sure whether this could be repeating question or not but not found proper answer in my context so asking. I am using alpine js for one of the frontend applications that I am currently working on and i am in need to manage html templates effectively in javascript. Moreover, those template can be just plain templates or event based.

So let's say I have dragstart event where I am passing whole template as event data using dataTranser method. So defining template inline looks weird as I have to use " to generate them as quote otherwise everything breaks.

<li draggable="true" class="databoard-grid-draggable"
    :id="$id('databoard-grid-draggable')"
    @dragstart="(event) => {
        let insertHTML = `
            <div class='w-100' x-data='{visualType: &quot;text&quot; }'>
                Some long template html here
            </div>`;
        event.dataTransfer.setData('text/html', insertHTML);
        event.dataTransfer.setData('filterable', true);
    }">
    <a class="dropdown-item fs-6" href="javascript:void(0)"
        x-text="subModule.name"></a>
</li>

and even in js part, where I am receiving this entire html code is something like this. here addwidget's first parameter only accepts html as string. Gridstack is the used library here for that purpose.

staticGrid.addWidget(`
    <div x-data  class="grid-stack-item"
        @dragover.prevent @drop.prevent="(event) => {
            $(event.target).removeClass('sortable-placeholder');
            let grid = document.querySelector('#movable-grid-stack').gridstack;
            grid.addWidget(window.getMovableGridHTML(event), {
                x: $el.getAttribute('gs-x'),
                y: $el.getAttribute('gs-y'),
                w: $el.getAttribute('gs-w'),
                h: $el.getAttribute('gs-h'),
                autoPosition: false,
            })
        }">
        <div class="grid-stack-item-content h-auto"></div>
    </div>
`,gridStackWidget);

and even worst that I am also getting inner grid's html from somewhere else with grid.addWidget(window.getMovableGridHTML(event) and then I have to define method called getMovableGridHTML which returns html based on event that is passed inside.

var getMovableGridHTML = (event) => {
                //filterHTML for view of applied filters
                let filterHTML = '';
                if(event.dataTransfer.getData('filterable')) {
                    filterHTML =  document.getElementById('filterhtml').innerHTML;
                }

                let gridHTML =
                `<div class="grid-stack-item"
                    x-data="{
                        editMode: false,
                        filterable: ${event.dataTransfer.getData('filterable') ? true: false}
                    }"
                    :class="editMode ? 'border border-primary': ''"
                    @click="() => {
                       //click things
                    }"
                    @click.outside="() => {
                        //click outside things
                    }">
                    <div class="grid-stack-item-content">` + event.dataTransfer.getData('text/html') + filterHTML +
                    `</div>
                </div>`;
                return gridHTML;
            }
            window.getMovableGridHTML = getMovableGridHTML;

So templating goes too much messy here which is not easy to deal with when someone says to add more things here. I can use backtick literals in js which now supports both type of quotes but still not feeling proper way to handle so many templates especially when they return html based on events.

How to solve this problem effectively?


Solution

  • Probably you need to use another framework/library to handle this amount of interactivity you are trying to achieve. This templates you are talking about are probably "components". You can try to look at more complex solutions (which require bundling your project for example). For example - svelte.