How Our Team Created a Holiday Greeting Card Generator From Scratch

Want to wish your loved ones a merry Christmas and happy holidays? In this post, we'll show you how to create a stunning Greeting Card Generator with Elementor! Heads Up – this one is for our advanced users.

It’s Christmas time, which means it is time for our Education team to come up with something special for you! We think we’ve come up with the perfect gift – a fully automated greeting card generator done entirely with Elementor.

Want to send greetings to your parents, family, or your best friend? All you have to do is fill in the details: your friend’s name – David for example, add a greeting with all your best wishes for the new year, and don’t forget to add a nice closing as well as your name – let’s say Jack.

Fill in the email field with David’s email, and hit the Deliver button. From there we are redirected to a personalized Thank You page that confirms the greeting card was sent successfully, and at the same time David receives an e-mail with a link to the greeting.

By clicking the link, David will be directed to the result page, and see the beautiful Christmas greeting made just for him.

A heads up in advance – this might get a little complicated, but we’ll go over it step by step, understand the logic behind it, see how things work behind the scenes, and then you’ll see it isn’t as complicated as you might’ve thought.

So let’s see what we’re up against by breaking it down and understand the bigger picture.


The first screen is the main page. You can see the form on the left, and the greeting card on the right.

The second screen is the result page. This is the page your friends land on after having clicked the link in the email they receive. Here they will see your beautifully designed Christmas greeting.

The third screen is the Thank You (or Email Confirmation page). This is the page you are redirected to after having sent the Greeting and confirms that the message was sent successfully.

We’ve designed and created these 3 pages with Elementor. So go ahead and create your own designs, because what we’re doing here can be applied to any design.

Main Page

First off, on the main page, we will focus on the first trick – real-time live preview. As you can see, while I’m filling in the form on the left, the greeting card on the right is mirroring the same text.

Let’s head over to the editor. As you can see, the page is the same, we just cleaned it up a bit so we can focus on the technical side of things.

We have a section with two columns – the column on the left has the form with all the fields we need. 

The column on the right has a bunch of form widgets stacked one on top of the other. We’ve also added a script to the HTML Widget you see here. This script helps us with the mirroring effect, and we’ve added some Custom CSS as well.

Let’s start off by understanding the relationship between the two columns and all of the forms. Each field in the form on the left corresponds with one of the fields in the forms on the right.

Now, let’s start off with the first field in the form on the left by filling in the necessary details: the type, label, placeholder, and let’s set the Required option to yes: 

Moving on to the Advanced tab – give the field a unique ID.

On the form on the right, all you need to do is just repeat what we did before, just make sure to give it a unique ID of its own.

Now, in order for the mirroring to take place, we need to add this script to the HTML widget:

It essentially allows us to connect the fields’ ID’s, which in turn allows for the ‘live preview’ state. You can place it anywhere on your page. You can go ahead and add your own fields, as many as you like.

This helped us create a virtual hoiday greeting card, allowing us to preview it before sending it on to your family or friends.

Now, let’s make some minor adjustments in the advanced tab. Go to Custom CSS and paste this code:

This needs to be done in all of the form widgets on the right column and will remove the buttons, the ‘focus’ state border, and align all the text to the middle.

Pay attention though – in order to remove all of the buttons, you’ll need to give each one a unique ID.

Actions After Submit

Moving on to part 2 – actions after submit. The ‘Actions after submit’ option in the form widget allows us to set an action that will be performed after a user submits the form.

We will add two actions. Let’s start with the first one:

Click on the ‘add action’ field and in the Dropdown, choose ’email’. You’ll find a new ‘email’ tab below. It comes with pre-built parameters, but we can change any of those as we wish. We can set the receiver’s email, a subject, the message, and more. 

In the message field, we can add HTML as well, this way we can customize the message in the email. You can find HTML tags easily via google search.

Now, let’s focus on the second trick –

The link inside the email message your friend receives, needs to be dynamic for it to create personalized content.

In the past months, we’ve really improved Elementor’s dynamic abilities. Which gets us right to the next action – Request Parameter. Before we understand how it works, let’s see what it does:

The form knows how to take all the parameters filled inside it, send an email to our friend who upon clicking the link in the email, will see the custom Christmas greeting with all the details we filled in on the form.

Result Page

Now, Let’s see how to set up the Result page. Let’s start off by dragging in the Heading widget. Then, in the Content tab, under Title, click on DYNAMIC and under Site choose the Request Parameter.

Click on the request parameter field and in the settings dropdown, make sure the Type is set to GET… it should so by default. The GET field allows us to receive data from the URL. in our case, the data will arrive from the filled-in form connected to the link in the email.

Go ahead and fill in the parameter name. In This case, I’ve used ‘fname’. We also added some fallback text in the Advanced Dropdown. Just make sure that the parameter name is written altogether, without any spaces in between and use Latin characters. You can also use the dash and underline symbols.

Now that we’ve added names to all of the parameters, we can go back to the email section in the form on the main page and define the fields’ parameter names as well, this way we connect them up with the dynamic fields on the result page. We also need to transfer the data via the link sent in the email to your friend. 

Sounds a bit complicated, so let’s go over this link and see how it works:

First, in the link tag we see the url of the result page. The question mark separates the domain from the query string, which contains all of the different parameters we defined before.

Now, let’s look at it a bit closer. Fname is equal to its corresponding field ID in the result page. In our case it is equal to ID name1.

Let’s see another example, Message is equal to its corresponding field ID in the result page. In our case it is equal to ID message1.
As you can see, this way we link the parameters from the result page, to the fields from the main page, where each parameter has its corresponding field.

This is where the magic happens. The link we send connects the fields of the main page to the dynamic parameters of the Result page. Let’s go through the whole link and see that we have all the fields. Between each field we make sure to have the Ampersand symbol, it separates them.

Thank You Page

Now all that’s left is to talk about the Thank You pageThis page informs the sender that the message was sent successfully. 

We need to go back to the form on the main page, and under ‘Actions after submit’, choose Redirect. In the Redirect To field, fill in the link of the Thank You page. In this case, the name of the sender is also connected so that the Thank You page is personalized as well.

That’s it, we’re done! Of course, you can send as many wishes as you like, each time the content changes dynamically. 

From all of us at Elementor, we wish you a Merry Christmas and a Happy New Year!

About the Author

Aviv Umflat
Aviv Umflat
Aviv is a web designer at Elementor, with over 10 years of experience. He loves to sleep, make sarcastic remarks and eat falafel.

Share on

Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp

you might also like

Liked This Article?

We have a lot more where that came from! Join 1,353,229 subscribers who stay ahead of the pack.

By entering your email, you agree to our Terms of Service and Privacy Policy.


33 Responses

    1. The images are not available for download due to copyright issues. In principle, the size of the image depends on the number of fields and the amount of text, so it’s a trial and error process to figure out what is the right image size for the project.

  1. How can this work for a general mass send, if not inputting the Recipients personal name & left blank, so the card can be sent to multiple recipients?

    Pro version subscriber

  2. I think it is a great idea and show us the potential behind this amazing tool you create. Although it is a beat advanced for the most average users the tutorial helps understand the process. How did you make the snow effect on the Background? Thanks. Fábio

    1. There could be different reasons why you get this error message. For example, if you didn’t put the right ID’s for the input and output. But it’s difficult to tell you exactly why.

      1. I had the same problem. The issue was with my security plugin (Wordfence Security in my case). If you temporarily deactivate it while editing the page, it will work fine. Cheers

  3. Is there any way to download this and we will input our own pictures? more or less fill in the blanks 😉
    thank you for the GREAT Idea!!

  4. How did everyone do getting this up and running? I am new with this and after hours of trial and error and running out of time giving up ;-( but had fun trying !

  5. I absolutely love this! Great job!!!!!
    I was thinking to take it a step or 2 further, with your help of-course.
    1. adding a dynamic image gallery to the form, allowing you to select any image of your choice from the gallery, which gets parsed along with the rest of the form
    2. duplicate the js script and move the duplicate script out from the inner-section into the containing column and then adapt the duplicate script to display the selected image as a background for the inner-section.
    Rgds, R

  6. Check that your security plugin is not doing the blocking. I had the same issue and had to deactivate Wordfence Security while editing the page in Elementor and it fixed it. Cheers

  7. Hi, this is inspiring! May I ask a question – the html for the results page chops the url at the first space in the message – it does not add wildcards, so it cannot display properly. What could be the problem? if the field ids are used anywhere but the link they work fine. Help! 🙂

  8. Hi guys. Thanks for the cool demo. I have tried setting this up and it works great…up to a point. I am having a problem when any of the fields contain multiple words. In essence the url that is created (which the receiver gets in their email) gets cut off at the first blank space between the words. I was expecting the spaces to be replaced by wildcards, instead the url gets cut off and is incomplete. Any suggestions as to why that may be happening? Thank you in advance!

  9. This is really great!

    So the bit of script for the live preview does not seem to work with date, time or select fields. It works with the date/time fields if you manually type in the date/time, but not if you use the date or time picker.

    How can I make it so those fields work with the live preview?

  10. Hello,

    This looks excellent!

    Please can you or (anyone else) share the code for this? The video says it included but I am not able to find it anywhere.


  11. Not sure where the code went from this post, but here’s what I use on a birthday card invite system:

    setTimeout( function() {
    jQuery( document ).ready( function( $ ) {
    $( ‘#form-field-name1’ ).keyup( function () {
    $( ‘#form-field-name2’ ).val( $( this ).val() );
    } );

    $( ‘#form-field-bi_input_message’ ).keyup( function () {
    $( ‘#form-field-bi_output_message’ ).val( $( this ).val() );
    } );

    $( ‘#form-field-bi_input_date’ ).focusout( function () {
    $( ‘#form-field-bi_output_date’ ).val( $( this ).val() );
    } );

    $( ‘#form-field-bi_input_time’ ).mouseup( function () {
    $( ‘#form-field-bi_output_time’ ).val( $( this ).val() );
    } );

    $( ‘#form-field-bi_input_location’ ).focusout( function () {
    $( ‘#form-field-bi_output_location’ ).val( $( this ).val() );
    } );

    $( ‘#form-field-bi_input_from’ ).keyup( function () {
    $( ‘#form-field-bi_output_from’ ).val( $( this ).val() );
    } );
    }, 2000 );


    Taking this example:

    function( $ ) {
    $( ‘#form-field-name1’ ).keyup( function () {
    $( ‘#form-field-name2’ ).val( $( this ).val() );

    You would take the #form-field-name1 and replace it with the css ID of the input field on the form on the left and the #form-field-name2 would be replaced with the input field css ID on the form on the right that you want populated with the first input field from the form on the left. (This is described in the video)

    Here is the CSS Code that I used:

    #bi_output_rec_name_button {
    display: none;
    selector #form-field-name2 {
    text-align: center;
    selector .elementor-field-group .elementor-field-textual:focus {
    -webkit-box-shadow: 0 0 0 1px rgba(0,0,0,0) inset;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0);
    outline: 0;

    selector input {
    background-color: rgb(0,0,0,0) !important;
    color: rgba(97,151,218,0.76);
    font-family: allura;

    selector ::placeholder {
    color: #3a79d0;
    font-family: allura;


    It’s very similar to the code used in the video, but is modified. Compare and use what you need.

Leave a Reply

Your email address will not be published. Required fields are marked *

Want to learn how to build better websites?

Join 1,353,229 Elementors, and get a weekly roundup of our best skill-enhancing content.

By entering your email, you agree to our Terms of Service and Privacy Policy.