Contacts Card
Let us now create an application that interacts with CRM data. It should fetch the Contacts records and represent them as cards.
Iteration - 1
Create application in VTAP (contact_cards). Navigate Main Menu > Platform > App Creator > Add App
Fill the Form And Save
Clicking on ContactCards App will open an editor where you can customise your App
resources/index.js
We will be using VueJS library along with VCAP (Vtiger Custom Application) runtime that provides userapi that helps you work with CRM records easily.
window.addEventListener('DOMContentLoaded', function() {
new Vue({
el: "#app",
data: {
contacts: []
},
mounted: function() {
VCAP.userapi.records.get({module: "Contacts"}, (e, contacts) => {
this.contacts = contacts;
});
}
});
});
Click Ctrl+S to Save the changes
views/index.html
<!DOCTYPE html>
<html>
<head>
<title>Contacts</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
<link rel="stylesheet" href="resources/index.css">
</head>
<body>
<div id="app" class="container-fluid bg-dark" style="height: 100%" v-cloak>
<div v-if="contacts" class="row">
<div class="card m-4" style="width: 350px" v-for="c in contacts">
<div class="card-body">
<h5 class="card-title">{{c.firstname}} {{c.lastname}}</h5>
<p class="card-text">{{c.title}}</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item"><i class="fa-solid fa-envelope"></i> {{c.email}}</li>
<li class="list-group-item"><i class="fa-solid fa-phone"></i> {{c.phone ? c.phone : '-'}}</li>
</ul>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script>
<script src="resources/vcap.js"> </script>
<script src="resources/index.js"> </script>
</body>
</html>
Click Ctrl+S to Save the changes
Publish the changes. Launch the application.
Iteration - 2
Lets try to refactor HTML to move the card representation as a VueJS component.
resources/index.js
Define a crm-contact component that renders information as a card.
window.addEventListener('DOMContentLoaded', function() {
Vue.component('crm-contact', {
props: ['info'],
template: `
<div class="card m-4" style="width: 350px">
<div class="card-body">
<h5 class="card-title">{{info.firstname}} {{info.lastname}}</h5>
<p class="card-text">{{info.title}}</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item"><i class="fa-solid fa-envelope"></i> {{info.email}}</li>
<li class="list-group-item"><i class="fa-solid fa-phone"></i> {{info.phone ? info.phone : '-'}}</li>
</ul>
</div>
`
});
new Vue({
el: "#app",
data: {
contacts: []
},
mounted: function() {
VCAP.userapi.records.get({module: "Contacts"}, (e, contacts) => {
this.contacts = contacts;
});
}
});
});
Click Ctrl+S to Save the changes
views/index.html
Use the crm-contact card tag in the HTML now.
<!DOCTYPE html>
<html>
<head>
<title>Contacts</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
<link rel="stylesheet" href="resources/index.css">
</head>
<body>
<div id="app" class="container-fluid bg-dark" style="height: 100%" v-cloak>
<div v-if="contacts" class="row">
<crm-contact v-for="c in contacts" :info="c"></crm-contact>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script>
<script src="resources/vcap.js"> </script>
<script src="resources/index.js"> </script>
</body>
</html>
Click Ctrl+S to Save the changes
Publish the changes. Launch the application.