<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohamed Termoul</title>
    <description>The latest articles on DEV Community by Mohamed Termoul (@mtermoul).</description>
    <link>https://dev.to/mtermoul</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F152499%2F32ea088b-e9d7-4682-8e8d-311affe49d7d.jpeg</url>
      <title>DEV Community: Mohamed Termoul</title>
      <link>https://dev.to/mtermoul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mtermoul"/>
    <language>en</language>
    <item>
      <title>5 ways to change component colors and styles using Vuetify</title>
      <dc:creator>Mohamed Termoul</dc:creator>
      <pubDate>Sun, 16 Feb 2020 22:14:14 +0000</pubDate>
      <link>https://dev.to/mtermoul/5-ways-to-change-component-colors-and-styles-using-vuetify-3ee9</link>
      <guid>https://dev.to/mtermoul/5-ways-to-change-component-colors-and-styles-using-vuetify-3ee9</guid>
      <description>&lt;p&gt;When I started using using Vue as my front-end framework, I tried to use it with Bootstrap of just plain old CSS. However soon, I realized that things were not as fast as I wished. Then I discovered Vuetify as the Material Design CSS/Components framework that can be used along Vue.js to supercharge your development tools. So what I wanted to quickly address in this article is how can you style your components using Vue. The most common way that come to mind is using plain old CSS. However Vuetify has slightly different approach. So let’s digg in and see the different way you can style components, and which way is the productive way.&lt;/p&gt;

&lt;h1&gt;
  
  
  1- Using component props
&lt;/h1&gt;

&lt;p&gt;Many components has props that allow quick style change. For instance the &lt;code&gt;v-card&lt;/code&gt; &lt;code&gt;v-btn&lt;/code&gt; &lt;code&gt;v-chip&lt;/code&gt; and many components have the &lt;code&gt;color&lt;/code&gt; property which you can set like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;v-card color="orange"&amp;gt;...&amp;lt;/v-card&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Other props that allow for quick style change would be something like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;v-container px-2&amp;gt;...&amp;lt;/v-container&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in this case we are changing the paddings on this component by using this prop.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2368%2F1%2AeY0y4WW9WfGUiJvtx9z3DQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2368%2F1%2AeY0y4WW9WfGUiJvtx9z3DQ.png" alt="HomePage preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see above, you can simply control the color, padding, alignment of the card component by just using few props without the need to use CSS at all&lt;/p&gt;

&lt;h1&gt;
  
  
  2- Using the class property
&lt;/h1&gt;

&lt;p&gt;Every Vuetify component comes with a very handy property called class . And you can use that class to change many styling props like the color, font, padding, alignment… However you need to know which CSS classes to use in order to make the changes. Vuetify have already defined many CSS classes to control many style. For instance to change the font color to red you simply say &lt;code&gt;class="red--text"&lt;/code&gt; or to change the typography or the fonts you can use one of the predefined font styles like this &lt;code&gt;class="subtitle-2"&lt;/code&gt; . You can also change the background color of a component using the class prop like this &lt;code&gt;class="grey"&lt;/code&gt; let’s change the the example above to use the class property.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see in the code above, we changed the color of text and background using class prop. We also change the font in the same way. I also want to mention that Vuetify have created the CSS classes for all these styles and made them available for us to use without the need to touch the actual CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AAraNUUmcO4wIljHjI1tEhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AAraNUUmcO4wIljHjI1tEhw.png" alt="HomePage preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3- Using in-component style and CSS
&lt;/h1&gt;

&lt;p&gt;The third option that Vuetify encourages is using CSS styling within the single file components. In this method you simply write plain old css inside the &lt;code&gt;&amp;lt;style&amp;gt;...&amp;lt;/style&amp;gt;&lt;/code&gt; tag within your component. Let's see how we can change few styles using this approach&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;It is worth mentioning that in order for you to use css, you need to know CSS selection queries syntax. Meaning if you want to change the card tilte text to italic, then you need to know how to select that div only. For this I used the Chrome dev tools to inspect the title to see what's the class name for that div. Then I used css to change the style like this &lt;code&gt;.v-card__title { font-style: italic; }&lt;/code&gt; so in this case I relied on Vuetify classes. Other than that this method will allow you to use your plain old CSS tricks to style about anything. My rule of thumb, is don't use this method unless Vuetify does not have any prop or class that does what you are looking for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AFftRe7GCHMvx6CzZcvJ5Hg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2AFftRe7GCHMvx6CzZcvJ5Hg.png" alt="HomePage preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  4- Using a stand alone CSS file
&lt;/h1&gt;

&lt;p&gt;In this method, we will be using plain old CSS tricks like the method above, except that we will be writing our css in an external CSS file. This method would be more suitable if we have shared css that will be used by multiple components. The way to implement this is to save the css file under &lt;code&gt;assets/styles/main.css&lt;/code&gt; then import it within specific component or from the &lt;code&gt;App.vue&lt;/code&gt; like this:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;&amp;lt;template&amp;gt;&lt;br&gt;
...&lt;br&gt;
&amp;lt;/template&amp;gt;&lt;br&gt;
&amp;lt;script&amp;gt;&lt;br&gt;
...&lt;br&gt;
&amp;lt;/script&amp;gt;&lt;br&gt;
&amp;lt;style&amp;gt;&lt;br&gt;
@import './assets/styles/main.css'&lt;br&gt;
&amp;lt;/style&amp;gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;As you can see in the example above, Vuetify and Vue is very flexible in terms how to acheive some tasks. However you have to use some caution on how to use the methods mentioned above and use the recomended way first before unleashing the power of the full raw CSS files.&lt;br&gt;
Also coming in another article the 5th way which will be covered in my next article on how to change styles using themes and SASS variables.&lt;br&gt;
Thanks for reading and let me know what is your prefered way or may be another way not mentioned here.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuetify</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>How to Build a Single-Page Sales Funnel App using Node.js, Cosmic JS and Stripe</title>
      <dc:creator>Mohamed Termoul</dc:creator>
      <pubDate>Wed, 15 May 2019 19:21:54 +0000</pubDate>
      <link>https://dev.to/mtermoul/how-to-build-a-single-page-sales-funnel-app-using-node-js-cosmic-js-and-stripe-1lp2</link>
      <guid>https://dev.to/mtermoul/how-to-build-a-single-page-sales-funnel-app-using-node-js-cosmic-js-and-stripe-1lp2</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a Single-Page Sales Funnel App using Node.js, Cosmic JS and Stripe
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xWs7PSkb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cosmic-s3.imgix.net/fba84950-7534-11e9-97c3-f3f149e9cf49-smartmockupsmain.jpg%3Fw%3D1000" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xWs7PSkb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cosmic-s3.imgix.net/fba84950-7534-11e9-97c3-f3f149e9cf49-smartmockupsmain.jpg%3Fw%3D1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is a sales funnel? And why is it important? A sales funnel is a path that your website's visitors take before purchasing a product. If you don’t understand your sales funnel, you can’t optimize it. Building a great sales funnel can influence how visitors move through the funnel and whether they eventually convert. In this little demo I will be showing you how to build a simple, one-page sales funnel using Node JS, Cosmic JS, and Stripe for handling credit card payments.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cosmicjs.com/apps/single-page-sales-funnel"&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cosmicjs/nodejs-sales-page"&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stripe.com/docs/stripe-js/elements/quickstart/"&gt;Stripe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cosmicjs.com/"&gt;Cosmic JS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why did I pick Cosmic JS
&lt;/h2&gt;

&lt;p&gt;If you need to build a sales page quickly and freely, you can simply sign up for a free Cosmic JS account, copy my app, customize it and you're done. You'll have you sale funnel page ready in minutes. If you need to add a section or features then you can simply download the source-code and change any of the markup or the JavaScript behind this application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to clone your own version of this app:
&lt;/h2&gt;

&lt;p&gt;In order for you to clone this application and have your own custom copy, you need to following these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up for a free Cosmic JS account&lt;/li&gt;
&lt;li&gt;Login into Cosmic JS account&lt;/li&gt;
&lt;li&gt;Go to the &lt;a href="https://cosmicjs.com/buckets"&gt;buckets&lt;/a&gt; page&lt;/li&gt;
&lt;li&gt;Click on &lt;code&gt;Add New Bucket&lt;/code&gt; button on the top right of the page&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Choose an app below option&lt;/code&gt; and scroll to the applications list&lt;/li&gt;
&lt;li&gt;Try to find the &lt;code&gt;Sales Funnel&lt;/code&gt; application&lt;/li&gt;
&lt;li&gt;Once you open the application click on the &lt;code&gt;Install Free&lt;/code&gt; button&lt;/li&gt;
&lt;li&gt;You can keep the same title and hit the &lt;code&gt;Install App&lt;/code&gt; button to confirm&lt;/li&gt;
&lt;li&gt;Then you will be taken to the application bucket&lt;/li&gt;
&lt;li&gt;Then you need to clone the github repo. Open the terminal window and type:&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/cosmicjs/nodejs-sales-page
cd crowd-pitch
npm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;edit and change Cosmic JS and Stripe API keys located in &lt;code&gt;/crowd-pitch/.env.local&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COSMIC_BUCKET=your-bucket-slug
COSMIC_READ_KEY=your-cosmic-read-key
COSMIC_WRITE_KEY=your-cosmic-write-key
STRIPE_KEY=your-stripe-api-key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Run the app server on your local machine&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# start the app
npm run server

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;open the application from your browser on &lt;a href="http://localhost:3000"&gt;&lt;/a&gt;&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How to customize the application content
&lt;/h2&gt;

&lt;p&gt;In order for you to change the text, images, and application content you need to follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to &lt;a href="https://cosmicjs.com/buckets"&gt;Cosmic JS dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go to buckets --&amp;gt; crowd-pitch&lt;/li&gt;
&lt;li&gt;Go to Pages --&amp;gt; Google cash machine&lt;/li&gt;
&lt;li&gt;Change the pages section by editing the text for each part of the web page like the page title, header....&lt;/li&gt;
&lt;li&gt;Change the page images by adding your own images. Make sure to keep the same image title and slug.&lt;/li&gt;
&lt;li&gt;Hit save and publish&lt;/li&gt;
&lt;li&gt;This part works like any CMS system, where you make changes to the back-end and the site can change immediately.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How to add new features to this application
&lt;/h2&gt;

&lt;p&gt;This part and below would be an explanation on how the application front-end was developed and how you can dig deeper to customize more options like the layout, css, colors, and which fields to collect from the user. This application was build mainly using Node JS, and Stripe API. So let's take a look at the server.js file&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see from the code above we are using the following Javascript components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/express"&gt;Express:&lt;/a&gt; a light weight web server for node&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/express-handlebars"&gt;Express-Handlebars:&lt;/a&gt; This html templating library for handlebars.js syntax&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://handlebarsjs.com/"&gt;CosmicJs:&lt;/a&gt; to handle interaction with Cosmic JS API from the server&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/stripe"&gt;Stripe:&lt;/a&gt; to handle interaction with &lt;a href="https://stripe.com/docs/payments"&gt;Stripe payment API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside the server.js there is basically two function to handle server routing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app.get('/') to handle the get request when the user visits the application. Inside this function we simply call Cosmic JS to fetch all data from our bucket and inject it as a server response local variable. The second part is just rendering the home view which is just an HTML/Handlebars template page.&lt;/li&gt;
&lt;li&gt;app.post('/pay') to handle the payment form posting. Inside this function there is simply one call to Stripe charges API to add one charge to the specified credit card.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to customize the layout and CSS for the application?
&lt;/h2&gt;

&lt;p&gt;As mentioned before, in this app we are using handlebars.js for the page templating. From the server get function we render &lt;code&gt;views/home.handlebars&lt;/code&gt; page which is simply an html page with some handlebars tags to replace server variables with values from Cosmic JS CMS. Let's take a look:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, we reference server variables within a double curly brackets. For instance &lt;code&gt;{{ cosmic.metadata.top_logo.url }}&lt;/code&gt; means get the value of variable from Cosmic JS, which the logo image url and put it in the home view page. There are also similar syntax to handle if and loop using handlebars syntax. For a full syntax help, please refer to &lt;a href="http://handlebarsjs.com/"&gt;Handlebars User Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also change some of the styling of the page from within home view page because we are simply using &lt;a href="https://getbootstrap.com/docs/4.3/getting-started/introduction/"&gt;Bootstrap framework&lt;/a&gt;. For some other styling properties you can change it directly from &lt;code&gt;/public/css/styles.css&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For the application layout there the file &lt;code&gt;/views/layouts/main.handlebars&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is basically the main html template for every page in our application. It's worth mentioning that we are referencing a couple of libraries from the client side like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JQuery&lt;/li&gt;
&lt;li&gt;Stripe&lt;/li&gt;
&lt;li&gt;Bootstrap&lt;/li&gt;
&lt;li&gt;Font-awesome&lt;/li&gt;
&lt;li&gt;Axios.js to handle Ajax calls&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Handling credit card payment with Stripe and Axios
&lt;/h2&gt;

&lt;p&gt;To accept credit card payments in our application we use three steps process.&lt;/p&gt;

&lt;p&gt;first we use &lt;a href="https://stripe.com/docs/stripe-js/elements/quickstart"&gt;Stripe card elements&lt;/a&gt; to inject the credit card input element inside our html form.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Validate the credit card info by calling stripe.createToken when the user hit the submit payment button. This function will simply send the info to Strip API and get a valid token if success. Otherwise it will return an invalid token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post the payment form form data to the server post method. This method will take data submitted from the client form and submit them again as a stripe charge by calling stripe.charges.create. Take a look:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, once the charge is sent to stripe, we will return success to the client if no errors from Stripe. Otherwise we will emit Stripe errors back to the client.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The last step is on the client side, we will display the payment result on the client form if success, or the error message if the payment fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to add multiple page funnel to my application.
&lt;/h2&gt;

&lt;p&gt;Sometimes the application will need more than one page to capture the user final action. If you want to do that, you can simply add more pages to the server view, more routes, and handle the post from one page to the other either via javascript functions or server post methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the main.js file?
&lt;/h2&gt;

&lt;p&gt;This file contains one function right now to handle count down counter. However you can use it if you any other javascript interactions with your user. For the count down counter we store a variable on Cosmic JS server called&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dealCountDown = {{ cosmic.metadata.deal_countdown }};

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and then we calls the &lt;code&gt;initializeClock&lt;/code&gt; function which will run the count down until this variable reaches zero.&lt;/p&gt;

&lt;p&gt;Take a look at the main.js file for the full implementation details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BQsnUfsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cosmic-s3.imgix.net/e8530730-7536-11e9-add3-5fb6959d341f-crowd-pitch-preview.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BQsnUfsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cosmic-s3.imgix.net/e8530730-7536-11e9-add3-5fb6959d341f-crowd-pitch-preview.gif" alt="Crowd-Pitch main view"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Check user engagement with A/B testing
&lt;/h2&gt;

&lt;p&gt;As most marketers have come to realize, the cost of acquiring any quality traffic can be huge. A/B testing lets you make the most out of your existing traffic and helps you increase conversion without having to spend on acquiring new traffic. A/B testing can give you high ROI as sometimes, even the most minor changes can result in a significant increase in conversions.&lt;br&gt;
For the purpose of this app, I will add two &lt;code&gt;style.css&lt;/code&gt; files and once the user visits the site I will be randomly selecting one stylesheet. The stylesheet selection will affect how the color theme will look like. So basically the user can see either version A of the site or version B.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Then we load either style A or B on the &lt;code&gt;main.handlebars&lt;/code&gt; file like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We also have a javascript variable that will be used during the payment process to capture which page the user is coming from. This info will be stored along Stripe charge information.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const pageSource = {{#if pageB}} 'pageB' {{else}} 'pageA' {{/if}};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;then we save the page source along the stripe charge on the server post method.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this application, I've demonstrated how you can build a page that displays product info and handles credit card payments by leveraging the power of the Cosmic JS CMS plus a few other libraries that handle the payment function. You can add a function that will send an email to the user after the payment is submitted. Or add a function to send a user to another secure page to all him to download the digital product. The Cosmic JS Community  has a lot of examples on how to handle integration with email functions, download functions, and third party platforms.&lt;/p&gt;

&lt;p&gt;As always, I really hope that you enjoyed this little app, and please do not hesitate to send me your thoughts or comments about what could I have done better.&lt;/p&gt;

&lt;p&gt;If you have any comments or questions about building apps with Cosmic JS, &lt;a href="https://twitter.com/cosmic_js"&gt;reach out to us on Twitter&lt;/a&gt; and &lt;a href="https://cosmicjs.com/community"&gt;join the conversation on Slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>stripe</category>
      <category>cosmicjs</category>
      <category>handlebars</category>
    </item>
    <item>
      <title>Add dynamic filters to your data with ease, using Vue and the Cosmic JS Rest API</title>
      <dc:creator>Mohamed Termoul</dc:creator>
      <pubDate>Thu, 04 Apr 2019 19:47:51 +0000</pubDate>
      <link>https://dev.to/mtermoul/add-dynamic-filters-to-your-data-with-ease-using-vue-cosmic-js-rest-api-445g</link>
      <guid>https://dev.to/mtermoul/add-dynamic-filters-to-your-data-with-ease-using-vue-cosmic-js-rest-api-445g</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pokv1u26kwxbo7q15zz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pokv1u26kwxbo7q15zz.jpg" alt="kw0vlvan5i4916wpkbvx.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://col-admin.cosmicapp1.co/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mtermoul/col-admin/" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vuex.vuejs.org/" rel="noopener noreferrer"&gt;Vuex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vuetifyjs.com/en/" rel="noopener noreferrer"&gt;Vuetify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cosmicjs.com/" rel="noopener noreferrer"&gt;Cosmic JS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Filtering data is one of the most common features of any data-facing application, whether it's a front-end application or a back-end application. The Filter function is used to find records in a table or a dataset that meets certain criteria. For example, if you have a list called Books in a webpage, and you want to only show books that are currently on sale. You could accomplish this using the filter function.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we building exactly?
&lt;/h2&gt;

&lt;p&gt;In this short tutorial we are building a single page web app with two parts. The first part will be a list of students. The list will be displayed in a table like structure with multiple columns for each student. Each column will correspond to a data attribute of the student record. The list will also have a summary line at the end that tells you the record count. This is the student data structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;student: {
    id: unique identifier,
    firstName: string,
    lastName: string,
    dob: date (date of birth),
    gpa: number,
    address: string,
    city: string,
    county: string,
    state: string,
    zip: number
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second part will be the filters that the user can use to filter the data with. Let's assume that the user can filter by any field displayed in the list. So to build generic filter functions, that can be used with multiple fields, we will need to group these filters by data type. And each data type will allow certain comparison operators. The following table illustrate this logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    string: [contains, startWith]
    date: [equal, greaterThan, lessThan, between]
    number: [equal, greaterThan, lessThan, between]
    lookup: [is, isNot]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So basically we can build 12 comparison function that we can use with all our fields or any fields that we may add in the future. So let's get started with our app and see how we can build these features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting your Vue app
&lt;/h2&gt;

&lt;p&gt;To start a new app, you will need to install &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; and open new terminal window and type the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# initiating new Vue app
vue create col-admin

Vue CLI v3.0.0-rc.9
┌───────────────────────────┐
│  Update available: 3.5.1  │
└───────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, Linter
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No

# adding other js libraries
vue add vue-cli-plugin-vuetify
? Choose a preset: Default (recommended)
✔  Successfully invoked generator for plugin: vue-cli-plugin-vuetify

# adding the backend library
npm install --save cosmicjs

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after this we should have our starter application ready to be customized. If you want to run the app, just open the terminal window and type &lt;code&gt;npm run serve&lt;/code&gt; and then open the application from your browser from this app default url &lt;code&gt;http://localhost:8080/&lt;/code&gt; and you're good to go to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup you Rest API with Cosmic JS
&lt;/h2&gt;

&lt;p&gt;As we mentioned earlier, the goal of this app is to display a list of students, and then use the filter functionality to narrow down the list. For this project we will use Cosmic JS to store our data, and also to server the data using the built-in Rest API that comes with Cosmic JS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signup for a free &lt;a href="https://cosmicjs.com/pricing" rel="noopener noreferrer"&gt;Cosmic JS&lt;/a&gt; account.&lt;/li&gt;
&lt;li&gt;Add new bucket from the &lt;a href="https://cosmicjs.com/buckets" rel="noopener noreferrer"&gt;development dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add new &lt;code&gt;Object Type&lt;/code&gt; from the dashboard. and specify the following attributes for this object type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw224v7v1o859bo8b4q70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw224v7v1o859bo8b4q70.png" alt="cosmic-js-students-table.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From the object type metafields tab, add the following fields:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    SID: text field,
    firstName: text field,
    lastName: text field,
    DOB: text field,
    GPA: text field,
    Address: text field,
    City: text field,
    County: text field,
    State: text field,
    Zip: text field
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add some data into the Students table. If you want you can copy my data table from Cosmic JS by importing my &lt;a href="https://cosmicjs.com/col-admin/dashboard" rel="noopener noreferrer"&gt;col-admin-bucket&lt;/a&gt; under your account. I have inserted about 300 records, so you don't have to type all these information manually.&lt;/li&gt;
&lt;li&gt;Access your Cosmic JS data via the built-in Rest API from this url: &lt;code&gt;https://api.cosmicjs.com/v1/col-admin/objects?type=students&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Take a look to the &lt;a href="https://cosmicjs.github.io/rest-api-docs/?javascript" rel="noopener noreferrer"&gt;Cosmic JS API Documentations&lt;/a&gt; for a detailed list of all the APIs available for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After this you should be able to access you backend data via the Rest API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add data store using Vuex
&lt;/h2&gt;

&lt;p&gt;Under our project root folder lets add new folder &lt;code&gt;./src/store/&lt;/code&gt; and move &lt;code&gt;./src/store.js&lt;/code&gt; under the store folder. We will also need to create new file under &lt;code&gt;./src/api/cosmic.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Cosmic = require('cosmicjs')

const config = {
    bucket: {
        slug: process.env.COSMIC_BUCKET || 'col-admin',
        read_key: process.env.COSMIC_READ_KEY,
        write_key: process.env.COSMIC_WRITE_KEY
    }
}

module.exports = Cosmic().bucket(config.bucket)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This small script will be used as Cosmic JS connection object.&lt;/p&gt;

&lt;p&gt;We will also need to create new file under &lt;code&gt;./src/store/modules/cosmic.js&lt;/code&gt; for all the Cosmic JS data related functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Cosmic from '../../api/cosmic' // used for Rest API

const actions = {
    async fetchStudents ({commit, dispatch}) {
        const recordLimit = 25
        let skipPos = 0
        let fetchMore = true

        while (fetchMore) {
            try {
                const params = {
                    type: 'students',
                    limit: recordLimit,
                    skip: skipPos
                }
                let res = await Cosmic.getObjects(params)
                if (res.objects &amp;amp;&amp;amp; res.objects.length) {
                    let data = res.objects.map((item) =&amp;gt; {
                        return {...item.metadata, id: item.metadata.sid,
                            firstName: item.metadata.firstname,
                            lastName: item.metadata.lastname }
                    })
                    commit('ADD_STUDENTS', data)
                    commit('SET_IS_DATA_READY', true)
                    // if fetched recodrs lenght is less than 25 then we have end of list
                    if (res.objects.length &amp;lt; recordLimit) fetchMore = false
                } else {
                    fetchMore = false
                }
                skipPos += recordLimit
            }
            catch (error) {
                console.log(error)
                fetchMore = false
            }
        }
        dispatch('fetchStates')
    }
}

export default {
    actions
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, we only have one function &lt;code&gt;fetchStudents&lt;/code&gt;. This function will call the Cosmic JS &lt;code&gt;getObjects&lt;/code&gt; to pull 25 records at a time. And it will do this inside a while loop until we reach the end or no more records can be found. We can identify the end of data of the data row count will be less than 25 records. After fetching all data from the Rest API we will call the &lt;code&gt;ADD_STUDENTS&lt;/code&gt; mutation to store these records inside Vuex state variable. For more info about Vuex store, please read the &lt;a href="https://vuex.vuejs.org" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is another call at the end of this function to &lt;code&gt;fetchStates&lt;/code&gt;. This function will simply loop through all students records and get the unique state code and store it in &lt;code&gt;states&lt;/code&gt; variable. This can be used later on the filter by state dropdown component.&lt;/p&gt;

&lt;p&gt;This is the rest of the Vuex store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Vue from 'vue'
import Vuex from 'vuex'
import _ from 'underscore'
import cosmicStore from './modules/cosmic'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        isDataReady: false,
        students: [],
        states: []
    },
    getters: {
        students (state) {
            return state.students
        },
        isDataReady (state) {
            return state.isDataReady
        },
        states (state) {
            return state.states
        }
    },
    mutations: {
        SET_STUDENTS (state, value) {
            state.students = value
        },
        SET_IS_DATA_READY (state, value) {
            state.isDataReady = value
        },
        ADD_STUDENTS (state, value) {
            state.students.push(...value)
        },
        SET_STATES (state, value) {
            state.states = value
        }
    },
    actions: {
        fetchStates ({commit, state}) {
            let states = []
            states = _.chain(state.students).pluck('state').uniq().sortBy((value) =&amp;gt; value).value()
            commit('SET_STATES', states)
        }
    },
    modules: {
        cosmicStore
    }
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Application styling with Vuetify
&lt;/h2&gt;

&lt;p&gt;For this project we will use &lt;a href="https://vuetifyjs.com/en/getting-started/quick-start" rel="noopener noreferrer"&gt;Vuetify&lt;/a&gt; as our fron-end components library. This is very helpful, especially if you like to use &lt;a href="https://material.io/design/introduction/" rel="noopener noreferrer"&gt;Google Material Design&lt;/a&gt; into your project without a lot of overhead. Plus Vuetify is awesome because it has tons of built-in UI components that are fully loaded. After adding Vuetify to your project using Vue CLI add command, you can just reference Vuetify components from your page templates.&lt;br&gt;
Let's take a look at the &lt;code&gt;App.vue&lt;/code&gt; main layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;v-app&amp;gt;
        &amp;lt;v-toolbar app color="green accent-4"&amp;gt;
            &amp;lt;v-icon&amp;gt;school&amp;lt;/v-icon&amp;gt;
            &amp;lt;v-toolbar-title v-text="title"&amp;gt;&amp;lt;/v-toolbar-title&amp;gt;
            &amp;lt;v-spacer&amp;gt;&amp;lt;/v-spacer&amp;gt;
        &amp;lt;/v-toolbar&amp;gt;

        &amp;lt;v-content&amp;gt;
            &amp;lt;router-view/&amp;gt;
        &amp;lt;/v-content&amp;gt;

        &amp;lt;v-footer :fixed="fixed" app color="green accent-4"&amp;gt;
            &amp;lt;span&amp;gt;&amp;amp;copy; 2017&amp;lt;/span&amp;gt;
        &amp;lt;/v-footer&amp;gt;
    &amp;lt;/v-app&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;

export default {
  name: 'App',
  data () {
    return {
      fixed: false,
      title: 'College Query'
    }
  }
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the template above you can see that our application page layout has three sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;v-toolbar: which is the top toolbar component&lt;/li&gt;
&lt;li&gt;v-content: which will contain the inner content of any page&lt;/li&gt;
&lt;li&gt;v-footer: which will have the app copyright and contact info&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding application view and components
&lt;/h2&gt;

&lt;p&gt;You may notice that under the './src' folder, there are two folders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;./src/components: this folder will be used to store all web components that can be used inside any page. Currently we don't use any components yet! but if our app become more complex, we could easily break each page into small components.&lt;/li&gt;
&lt;li&gt;./src/views: This folder is used to store views. A view is the equivilent to a web page. Currently we have the &lt;code&gt;Home.vue&lt;/code&gt; which is the main page, and the &lt;code&gt;About.vue&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding data-grid to main page
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;Home.vue&lt;/code&gt; page we will have two main sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data filters: which contains all filters that the user can select.&lt;/li&gt;
&lt;li&gt;data grid: this the students list displayed as a data grid component. For our purpose we will use Vuetify &lt;code&gt;data-table&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let's take a look at the home page template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;v-container grid-list-lg&amp;gt;
        &amp;lt;v-layout row wrap&amp;gt;
            &amp;lt;v-flex xs2&amp;gt;
                &amp;lt;v-select
                    :items="filterFields"
                    v-model="filterField"
                    label="Filter by"&amp;gt;
                &amp;lt;/v-select&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs2&amp;gt;
                &amp;lt;v-select
                    :items="filterOperators"
                    v-model="filterOperator"
                    label="Operator"&amp;gt;
                &amp;lt;/v-select&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs2 v-show="filterOperator &amp;amp;&amp;amp; filterType !== 'lookup'"&amp;gt;
                &amp;lt;v-text-field
                    name="filterTerm"
                    :label="filterTermLabel"
                    :mask="filterTermMask"
                    :rules='filterTermRules'
                    return-masked-value
                    v-model="filterTerm"
                &amp;gt;&amp;lt;/v-text-field&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs2 v-show="filterOperator === 'between'"&amp;gt;
                &amp;lt;v-text-field
                    name="filterTerm2"
                    :label="filterTermLabel"
                    :mask="filterTermMask"
                    :rules='filterTermRules'
                    return-masked-value
                    v-model="filterTerm2"
                &amp;gt;&amp;lt;/v-text-field&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs2 v-show="filterType === 'lookup'"&amp;gt;
                &amp;lt;v-autocomplete
                  :items="filterLookupItems"
                  :label="filterLookupLabel"
                  v-model="filterLookupValue"
                &amp;gt;&amp;lt;/v-autocomplete&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs2&amp;gt;
                &amp;lt;v-btn color="warning" @click="onClearAllFilters"&amp;gt;Clear All&amp;lt;/v-btn&amp;gt;
            &amp;lt;/v-flex&amp;gt;
            &amp;lt;v-flex xs12&amp;gt;

                &amp;lt;v-data-table
                    :headers="headers"
                    :items="filteredStudents"
                    xhide-actions
                    :pagination.sync="pagination"
                    :loading="!isDataReady"
                    class="elevation-1"&amp;gt;
                    &amp;lt;template slot="items" slot-scope="props"&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.id }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.firstName }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.lastName }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.dob | shortDate(dateFilterFormat) }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.gpa | gpaFloat }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.address }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.city }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.county }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.state }}&amp;lt;/td&amp;gt;
                        &amp;lt;td&amp;gt;{{ props.item.zip }}&amp;lt;/td&amp;gt;
                    &amp;lt;/template&amp;gt;

                    &amp;lt;template slot="pageText" slot-scope="props"&amp;gt;
                        Total rows: {{ props.itemsLength }}
                    &amp;lt;/template&amp;gt;

                &amp;lt;/v-data-table&amp;gt;

            &amp;lt;/v-flex&amp;gt;
        &amp;lt;/v-layout&amp;gt;
    &amp;lt;/v-container&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, from the code above. the &lt;code&gt;v-data-table&lt;/code&gt; component is using &lt;code&gt;filteredStudents&lt;/code&gt; variable as it's data source. Inside Vuex store we have two state variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;students: an array which contains all students that are fetched from the database.&lt;/li&gt;
&lt;li&gt;filterdStudents: an array which contains only the students matching the filter criteria. Initially, if no filter is selected, then this variable will have exact same value as the &lt;code&gt;students&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;data-table&lt;/code&gt; component also has three sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;headers: currently we store the header in a data variable called headers&lt;/li&gt;
&lt;li&gt;items: this is the data section which is feeding of &lt;code&gt;filteredStudents&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;footer: will display the pagination controls and the record count info&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding data filters UI components
&lt;/h2&gt;

&lt;p&gt;As seen in the Home.vue page template the filters components consist of the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filter By: currently we have to select one of the available fields like firstName, lastName, dob...&lt;/li&gt;
&lt;li&gt;Filter Operator: this will be something like &lt;code&gt;Contains&lt;/code&gt;, 'Start with', 'Greater than'... The operators will change based on the field type&lt;/li&gt;
&lt;li&gt;Filter Term: this is the user input for the selected filter. Currently we have two filter terms in case if we need to select a range. For instance if the user selects date of birth between, then we need two date input fields.&lt;/li&gt;
&lt;li&gt;Filter lookup: is a dropdown in case if the filter criteria needs to be selected from a given list. In our app, when we need to filter by State, then we need to select a value from a a dropdown field.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add filter functionality
&lt;/h2&gt;

&lt;p&gt;We can summarize the filter functionality by these variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    headers: [
        { text: 'ID', align: 'left', sortable: false, value: 'id' },
        { text: 'First', value: 'firstName' },
        { text: 'Last', value: 'lastName' },
        { text: 'DOB', value: 'dob', dataType: 'Date' },
        { text: 'GPA', value: 'gpa' },
        { text: 'Address', value: 'address' },
        { text: 'City', value: 'city' },
        { text: 'County', value: 'county' },
        { text: 'State', value: 'state' },
        { text: 'Zip', value: 'zip' }
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This the data table headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    filterFields: [
        {text: 'First Name', value: 'firstName', type: 'text'},
        {text: 'Last Name', value: 'lastName', type: 'text'},
        {text: 'DOB', value: 'dob', type: 'date'},
        {text: 'GPA', value: 'gpa', type: 'number'},
        {text: 'Address', value: 'address', type: 'text'},
        {text: 'City', value: 'city', type: 'text'},
        {text: 'County', value: 'county', type: 'text'},
        {text: 'Zip', value: 'zip', type: 'number'},
        {text: 'State', value: 'state', type: 'lookup'}
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the list of filter fields that the user can select. You can also see that I added a type for each filter field. Filter type will be used lated to decide which function will be called to run the filter operations. Many fields will have the same data types, therefore we don't need to call a separate function to filter by that field. We will call the same function for all fields that share the same data type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    filterDefs: {
        text: {contains: {display: 'Contains', function: this.filterByTextContains},
               startsWith: {display: 'Starts with', function: this.filterByTextStartsWith}},
        number: {equal: {display: 'Equal', function: this.filterByNumberEqual, decimalPoint: 1},
                 greater: {display: 'Greater than', function: this.filterByNumberGreater, decimalPoint: 1},
                 less: {display: 'Less than', function: this.filterByNumberLess, decimalPoint: 1},
                 between: {display: 'Between', function: this.filterByNumberBetween, decimalPoint: 1}},
        date: {equal: {display: 'Equal', function: this.filterByDateEqual, format: 'MM/DD/YYYY'},
                 greater: {display: 'Greater than', function: this.filterByDateGreater, format: 'MM/DD/YYYY'},
                 less: {display: 'Less than', function: this.filterByDateLess, format: 'MM/DD/YYYY'},
                 between: {display: 'Between', function: this.filterByDateBetween, format: 'MM/DD/YYYY'}},
        lookup: {is: {display: 'Is', function: this.filterByLookupIs},
                 isNot: {display: 'Is not', function: this.filterByLookupIsNot}}
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filterDefs variable will store information that tells our UI which operator to use on each field type. We also specify in this config variable, which Javascript function to call when we need to filter by the selected field. This variable is my own interpretation on how the filter function should be configured and designed, however you can certainly do without it, and use Javascript code with a lot of &lt;code&gt;if&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;The last piece is the actual Javascript functions that we will call for each filter type. I am not going to list all of them, but let's see few examples from the &lt;code&gt;Home.vue&lt;/code&gt; page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ...
    methods: {
        filterByTextContains (list, fieldName, fieldValue) {
            const re = new RegExp(fieldValue, 'i')
            return this.filterByRegExp(list, fieldName, fieldValue, re)
        },
        filterByTextStartsWith (list, fieldName, fieldValue) {
            const re = new RegExp('^' + fieldValue, 'i')
            return this.filterByRegExp(list, fieldName, fieldValue, re)
        },
        filterByRegExp(list, fieldName, fieldValue, regExp) {
            return list.filter(item =&amp;gt; {
                if(item[fieldName] !== undefined) {
                    return regExp.test(item[fieldName])
                } else {
                    return true
                }
            })
        },
    ...
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above have two functions &lt;code&gt;filterByTextContains&lt;/code&gt; and &lt;code&gt;filterByTextStartsWith&lt;/code&gt; which will be called each time the user uses the text field filter function. And behind those two functions we call &lt;code&gt;filterByRegExp&lt;/code&gt; which is basically a function that uses Javascript Regular expression function. In a similar way I have written filter functions for numeric fields, for date fields, and for lookup fields. I have used simple logic like date comparison, or array find, or plain old JS if statement. The most important part is that these function should be generic enough to work with any field, and expects few parameters like the data list that should be filtered, the field name and the field value. I encourage you to take a look at the code for &lt;a href="https://github.com/mtermoul/col-admin/blob/master/src/views/Home.vue" rel="noopener noreferrer"&gt;Home.vue&lt;/a&gt; for the full details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Vue computed properties, watchers, and filters
&lt;/h2&gt;

&lt;p&gt;You can also find inside './src/views/Home.vue' a couple methods under computed, watch, and filters. Here is how and why I use each type for.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Computed: I have used these computed properties for &lt;code&gt;students&lt;/code&gt;, &lt;code&gt;filteredStudents&lt;/code&gt;, &lt;code&gt;isDataReady&lt;/code&gt;, &lt;code&gt;states&lt;/code&gt;. these properties will update automatically anytime the underlying variables which comes from Vuex store changes. This is useful especially if you bind the computed properties to the UI elements, and make UI changes or toggle between UI sections whenever the data inside the computed properties got updated. For instance &lt;code&gt;isDataReady&lt;/code&gt; is used in the data table whenever it's &lt;code&gt;false&lt;/code&gt; then the UI will play a waiting animation progress bar that tells the user that the data is loading. Once the &lt;code&gt;idDataReady&lt;/code&gt; is updated to &lt;code&gt;true&lt;/code&gt;, then the is loading progress bar will disappear, and the table will show the actual data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watchers: I have used these watched properties &lt;code&gt;filterField&lt;/code&gt;, and &lt;code&gt;filterOperator&lt;/code&gt;. the difference is that the watched properties does not cache the value, and each time the underlying data changes, the function will be called. I have used this to update the filter UI elements on the home page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Filters: don't get confused Vue filters with data filtering. Filters are functions that you define in the logic, then use inside the html template to format a field value. For instance I have &lt;code&gt;shortDate&lt;/code&gt;, and &lt;code&gt;gpaFloat&lt;/code&gt; functions which are used to format date and float values to the desired display format. You can call the filter function from the html template using this syntax &lt;code&gt;&amp;lt;td&amp;gt;{{ props.item.gpa | gpaFloat }}&amp;lt;/td&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also want to mention that I have used Vue life cycle event hooks to initiate the data fetching from the back end whenever the application starts. I am doing that from the &lt;code&gt;./main.js&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
new Vue({
  store,
  router,
  render: h =&amp;gt; h(App),
  created () {
    this.$store.dispatch('fetchStudents')
  }
}).$mount('#app')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, on app created event we are calling Vuex action by invoking the dispatch methods. this is very useful if you want to trigger actions automatically without waiting for user actions.&lt;br&gt;
And this is the final result. Please take a look at the application demo for a test drive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqvpgcbrqtt0qb61kz8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqvpgcbrqtt0qb61kz8.gif" alt="4u3hhp7zio8aa21vxzcr.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At the end, I want to mention that building simple application like this sounds easy, however building an expandable app can take some thinking and a little planing to make sure that your code can easily allow future expanssions and changes without the need to rewrite the app.&lt;br&gt;
Also worth mentioning that, using an API ready back-end did certainly save us a lot of time. Lastly I want to add that after finishing the app I realize that the the Home.vue page could certainly be broken up into small components, and make it more readable and maintainable. So that would probably be the next step if you ever want to make a use of Vue Components.&lt;/p&gt;

&lt;p&gt;So, try the application &lt;a href="http://col-admin.cosmicapp1.co" rel="noopener noreferrer"&gt;demo&lt;/a&gt;, take a look at the &lt;a href="https://github.com/mtermoul/col-admin" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and let me know what you think.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuetify</category>
      <category>filter</category>
      <category>cosmicjs</category>
    </item>
  </channel>
</rss>
