Developer suggestions for improved UI Grid?

Following up on my previous post, here’s a trivial proof of concept that shows how incredibly powerful vue templates can be in the context of frappe forms.

Step 1. In any doctype form, create a new field of type HTML and use the following template in the “Options” box:

    <table id="cat-facts" class="table table-bordered">
        <caption style="caption-side: top;">Cat Facts</caption>
        <thead>
            <tr class="d-flex">
                <th class="col-3">ID</th>
                <th class="col-2">Date Created</th>
                <th class="col-7">Fact</th>
            </tr>
        </thead>
        <tbody>
            <tr v-if="facts_loading">
                <td style="text-align: center">
                    <div class="spinner-border spinner-border-sm text-secondary" role="status">
                        <span class="sr-only">Loading...</span>
                    </div>
                </td>
            </tr>
            <tr v-cloak class="d-flex" v-for="(fact, index) in cat_facts">
                <td class="col-3">{{ fact._id }}</td>
                <td class="col-2">{{ fact.createdAt.slice(0,10) }}</td>
                <td class="col-7">{{ fact.text }}</td>
            </tr>
            <tr v-cloak v-if="cat_facts.length === 0 && !facts_loading">
                <td style="font-style: italic">No data.</td>
            </tr>
        </tbody>
    </table>

(This is quite a bit longer than it needs to be because it has a few niceties added, such as a spinning wheel during load and a “No data.” row that appears if the table is empty.)

Step 2. Create a new client script for whatever doctype you’re using, and add this form javascript:

frappe.ui.form.on('Offer Term', {
	refresh(frm) {
		var vm = new Vue({ 
            el: "#cat-facts", 
            data: {
                facts_loading: true,
                cat_facts: []
            }
        });
        frm.vm = vm;
        
        $.get("https://cat-fact.herokuapp.com/facts/random?animal_type=cat&amount=5", (data) => {
            vm.facts_loading = false;
            vm.cat_facts = data;
        })
	}
})

Step 3. Load the doctype up and behold your creation:

It’s all pretty simple to set up. I haven’t used the component library @youssef mentioned, but it looks great and I suspect it’d be pretty straight forward to incorporate. If you need something more powerful than the built in widget library, Vue gives you almost limitless power.

5 Likes