How to Create Buttons with Dynamic Link using Custom Fields

How to Create Buttons with Dynamic Link using Custom Fields

Sometimes you may need a button that can show different links in different posts. That’s a button with dynamic link. There are different ways to create it, one of them is using custom fields. Links will be saved into custom fields then pulled out and put into the button automatically. And, that’s where the Meta Box plugin comes in handy.

Continue reading "How to Create Buttons with Dynamic Link using Custom Fields"

How to Create Online Reservation Form for Restaurants using Meta Box

How to Create Online Reservation Form for Restaurants using Meta Box

It is now so popular that restaurants allow customers to make online reservation from their website. So, today, I am going to have a tutorial on how to create an online submission form for that. However, it allows customers to not only provide their information but also choose a set of food or private room in advance if they want to. Furthermore, even the total amount will be figured out in the form as well.

An online reservation form allows customers to make reservations from website of the restaurants

But, please note that we do not process the payment in this tutorial. Just show the number to let your customer know the amount they will be charged.

Before Getting Started

Along with the Meta Box core plugin from wordpress.org, what will we need? It’ll be these extensions or just Meta Box AIO from the Developer Bundle or the Lifetime Bundle. They are all available there, in the Meta Box AIO.

Video Version

Step 1: Create a New Custom Post Type

Each reservation will be a post in this new post type. So, go to Meta Box > Post Types > New Post Type to create a new one.

Create a new custom post type for the reservation

We’ve had a video tutorial for post type configuring, please take a look.

Step 2: Create Custom Fields for the Reservation Form

A reservation form usually includes general fields such as name, phone number, email, number of adults and children, date and time, table or room. However, as I said above, my form will have a field for choosing a set of food and show the amount.

Create custom fields for the reservation form

There are some special and specific settings we should clarify here.

ID of the Full Name Field

I want the name of the customer to be the title of the post as well as the reservation, so I set this field’s ID as post_title.

The Options in the Set Lunch and Private Room Fields

These two fields are Select type, so they have the Choices section for entering the options.

set options with the values for custom fields of choosing a food set

You can see that on the left of the colon (:), I have the numbers. They are the price (USD) of the food set with the corresponding name on the right of the colon.

The same with the Private Room field. The price is on the left, and the name of the room is on the right.

set options with the values for the custom fields of choosing a private room

Display Custom Fields as Columns in the Admin Screen

For management purposes, restaurant owners usually want to see all the reservation information right from the admin screen. Thus, I will display the custom fields of the form as the columns in the All Reservations screen.

When we’ve activated the MB Admin Columns extension already, there is a section available in the field’s settings that is Show as an admin column. Tick it and then some others will appear for further configuration.

you must choose a position for the admin column

Please be notified that you must choose an option in the Column position to complete the setting of the admin column.

Finally, remember to choose the Reservation post type as the Location in the Settings tab of the field group.

remember to choose the location of the field group is reservation

So now, go to the Reservations menu, you will see the columns as follow:

the custom fields display as the admin columns to show information of the reservations for the restaurant owners

Step 3: Create the Reservation Page

My Reservation page will have a different look from the others on my website. So, I will create a new template for it. In the template folder of the theme, create a new file named reservation-page.php with this content:

<?php
/**
* Template Name: Reservation Page
*/
get_header();
if( have_posts() ) :
    while ( have_posts() ) :
        the_post();
        ?>
        <main id="main" class="site-main" role="main">
            <div class="col-left">
                <?php the_content(); ?>
                <div id="total1"></div>
            </div>
            <div class="col-right">
                <?php dynamic_sidebar( 'sidebar-1' );?>
            </div>
        </main>
        <?php
        endwhile;
endif;
get_footer();

In there, sidebar-1 is the ID of my pre-made sidebar.

using iframe to add Google Maps into sidebar of the reservation page

I embed an iframe of Google Maps to pin the restaurant’s address on the map as well as add other contact information about the restaurant. It may help customers easier to find the restaurant location and contact them in some special cases.

After applying this template for the reservation page, it has this look:

the reservation page with the maps and contact info of the restaurant

Add the Reservation Form to the Page

After having the MB Frontend Submission extension activated, this shortcode will be auto-generated.

MB Frontend submission extension generates the shortcode for the field group

It normally is in form of this:

[mb_frontend_form id='reservation' post_fields='title,content']

I will remove the attribute post_fields to not display the Title and Content fields, and as the submit_button attribute as well. Then, paste this code to the content of the reservation page.

paste the shortcode of the field group to the content of the page to show the field to the reservation page

Now, here is the page with the form.

the reservation form display on the frontend

Prettify the Reservation Page

It’s a kind of a rough-hewn gem and needs some polish. So, try some CSS.

#reservation {
  width: 100%; }

.page-template-reservation-page .site-main {
  width: 100%;
  display: grid; }

.no-sidebar .main {
  margin: 0; }

.rwmb-label, .rwmb-input {
  width: 100% !important;
  padding-bottom: 10px; }

.rwmb-input input {
  width: 100%; }

.rwmb-input select {
  width: 100%; }

.page-template-reservation-page .site-main {
  width: 100%;
  display: grid; }

@media all and (min-width: 768px) {
  .page-template-reservation-page .site-main {
    grid-template-columns: 1fr 30%;
    grid-gap: 30px; } }

.eci-info {
  font-size: 16px; }
  .eci-info svg {
    width: 20px !important;
    min-width: 20px !important;
    max-width: 20px !important;
    height: 20px !important; }

.rwmb-input-group-text {
  border: 0 !important; }

.rwmb-button {
  padding: 10px 25px;
  background: #ea0808;
  text-transform: uppercase; }

.calendar .rwmb-input, .adults .rwmb-input, .children .rwmb-input, .full-name .rwmb-input, .email .rwmb-input, .phone .rwmb-input, .book .rwmb-input, .black-tie .rwmb-input {
  position: relative;
  padding-bottom: 0; }
  .calendar .rwmb-input input, .calendar .rwmb-input select, .adults .rwmb-input input, .adults .rwmb-input select, .children .rwmb-input input, .children .rwmb-input select, .full-name .rwmb-input input, .full-name .rwmb-input select, .email .rwmb-input input, .email .rwmb-input select, .phone .rwmb-input input, .phone .rwmb-input select, .book .rwmb-input input, .book .rwmb-input select, .black-tie .rwmb-input input, .black-tie .rwmb-input select {
    padding-left: 40px; }
  .calendar .rwmb-input::before, .adults .rwmb-input::before, .children .rwmb-input::before, .full-name .rwmb-input::before, .email .rwmb-input::before, .phone .rwmb-input::before, .book .rwmb-input::before, .black-tie .rwmb-input::before {
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    text-decoration: inherit;
    color: #000;
    font-size: 18px;
    padding-right: 0.5em;
    position: absolute;
    top: 0px;
    bottom: 0;
    left: 0;
    background: #f0f0f0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px; }

.calendar .rwmb-input::before {
  content: "\f073"; }

.adults .rwmb-input::before, .children .rwmb-input::before, .full-name .rwmb-input::before {
  content: "\f007"; }

.email .rwmb-input::before {
  content: "\f003"; }

.phone .rwmb-input::before {
  content: "\f095"; }

.book .rwmb-input::before {
  content: "\f02d"; }

.black-tie .rwmb-input::before {
  content: "\f27e"; }

.col-left, .col-right {
  background: #efefef; }

.col-left {
  padding: 10px; }

.col-right .eci {
  padding: 10px;
  margin-top: 0;
}

In there, reservation-page is the name of the template file. And, for styling the fields, I set classes for those fields in their advanced settings and use those classes in this code such as calendar, adults, phone, book, etc.

I’m using FontAwesome here, so I must enqueue it in the functions.php file. If you add the above CSS to the style.css file as I did, you also need to enqueue it as well.

function child_theme_scripts() {
    wp_enqueue_style('font-awesome', 'https://cdn.jsdelivr.net/fontawesome/4.7.0/css/font-awesome.min.css', '', '4.7.0');
    wp_enqueue_style('estar-child-style', get_stylesheet_directory_uri() . '/style.css', false, '1.0', 'all');
}
add_action( 'wp_enqueue_scripts', 'child_theme_scripts' );

And now, the page turns to this look:

the reservation page after styling by CSS

Step 4: Add Functions to Figure Out the Amount

The Amount field is $0 so far no matter what you change the information in the fields many times. To figure out the amount then apply the number into this field, we must use code.

Create a Formula for the Amount

In the functions.php file, I’m adding this code:

add_action( 'wp_ajax_total', 'text_domain_load_total_ajax' );
add_action( 'wp_ajax_nopriv_total', 'text_domain_load_total_ajax' );
function text_domain_load_total_ajax() {
    $adults = $_POST['adults'] ?? 1;
    $children = $_POST['children'] ?? 0;
    $set_lunch = $_POST['set_lunch'] ?? 0;
    $private_room = $_POST['private_room'] ?? 0;
    $total = ( $adults * $set_lunch ) + ( $children * $set_lunch /2 ) + $private_room;
    $total = '$' . number_format($total, 2, '.', ',');
    wp_send_json_success( $total );
    die();
}

Explanation:

  • add_action (): is a hook to create an action named total;
  • text_domain_load_total_ajax(): is the function to load the values of all the variables and then put them into the formula;
  • $adults, $children, $set_lunch, $private_room: are the variables;
  • $adults = $_POST['adults'] ?? 1: is to check if the adults variable has any value. If it has, the value will be admitted. Otherwise, this variable will be applied to the default value, in this case, it is 1. You can set the default value as you want;
  • wp_send_json_success( $total ): is to return the value of the total variable in json.

Load the Values of the Variables

So far, no value has passed to any variable yet. All the variables are 0 or 1 as default value as I set in the above code.

Whenever customers change the option in the fields, the value of the options must be recognized and passed to those variables. To load those values, I need to create a script.js file in the js folder of the theme as follow:

(function($){
    $(document).ready(function(){
        $("#adults, #children, #set_lunch, #private_room").on( 'change', function(){
            var adults = $('#adults').val();
            var children = $('#children').val();
            var set_lunch = $('#set_lunch').val();
            var private_room = $('#private_room').val();
            console.log( set_lunch );
            $.ajax( {
                type: "post",
                dataType: "json",
                url : ReservationParams.ajaxURL,
                data: {
                    action: 'total',
                    adults: adults,
                    children: children,
                    set_lunch: set_lunch,
                    private_room: private_room
                },
                success: function(response) {
                    //console.log(response);
                    $('#amount').val(response.data);
                },
                error: function( jqXHR, textStatus, errorThrown ){
                    console.log( 'The following error occured: ' + textStatus, errorThrown );
                }
            } )
        } )
    })
})(jQuery)

create a JS file to load the value and send it to the function

You can see that I used ajax here to load the values. In there:

  • #adults, #children, #set_lunch, #private_room: are the IDs of the custom fields in the reservation form;
  • adults, children, set_lunch, private_room: are the variables using for the above formula, I’m assigning the values of the fields with the corresponding IDs to them;
  • action: 'total': The values are being sent by ajax to this action with the url is url : ReservationParams.ajaxURL;
  • success: function(response): if the request succeeds, this will call the value returned by the functions file then print to the custom field which has the ID as amount.

Enqueue the JS file and URL of AJAX

The formula hasn’t been run yet because we haven’t enqueued either the script.js file and the url of ajax. So now, add this code to the functions.php, inside the child_theme_scripts() function we have added before.

wp_enqueue_script( 'theme-script', get_stylesheet_directory_uri() . '/js/script.js', array( 'jquery' ), '1.0', true );
wp_localize_script( 'theme-script', 'ReservationParams', array( 'ajaxURL' => admin_url( 'admin-ajax.php' ) ) );

enqueue the JS file and URL of the AJAX in the functions file to enable them

Note:

  • 'theme-script': this name is the one you created, please pay attention that you must set it be the same in both lines;
  • 'ReservationParams' and 'ajaxURL' are from url : ReservationParams'.ajaxURL, you can change them, but do it at both.

Finally, everything is done. Let’s have a test.

check the reservation form operation and see it run well

You also can see that my first reservation is in posts management as well.

my test reservation show up in the admin screen will full information

Last Words

In fact, I have met just some cases that allow customers to order the food set and let them know the total amount in advance. I’m not sure that it is popular out there. However, it still is a good reference of operations in a submission form. I guess that you should have some variations when applying this tutorial, good luck!

Top Must-Read Blogs for Developers - P3 - JavaScript

Top Must-Read Blogs for Developers - P3 - JavaScript

Over the past 20 years, JavaScript has been the most popular programming language in the world. You can learn it quickly and apply it to various purposes, thus creating more opportunities for your career. That’s why we have selected the five best blogs about JavaScript in this series of top must-read blogs for developers. Maybe there will be at least an appropriate blog for you no matter what level you are at.

Continue reading "Top Must-Read Blogs for Developers - P3 - JavaScript"

How to Create Online Admission Form for School or University

How to Create Online Admission Form for School or University

Technology has been applied more and more popularly, even in education, and led to obvious changes in this special field. Notably, when the Covid-19 pandemic broke out and caused serious impacts on our lives, education institutions mostly started online teaching classes. As a result, school admission also can be done online. Students do not need to go to schools to hand in their profiles anymore. They can stay at home, and fill in their online admission forms. This can save expenses for traveling and delivery, as well as reduce risks of exposure. On the other hand, it helps the school office easily digitize the student’s data.

In this post, we are going to create an admission form for a university like that.

Continue reading "How to Create Online Admission Form for School or University"

How to Test a Plugin's Performance and Security

How to Test a Plugin's Performance and Security

Plugins can bring many advantages to your WordPress website. However, you should consider carefully before using one because it may contain viruses and malicious codes. They also may affect your website loading speed / performance. To check if a plugin has any issue, especially for a newly launched plugin, you can use various useful tools and follow the steps below.

Continue reading "How to Test a Plugin's Performance and Security"

Top Must-Read Blogs for Developers - P1

Top Must-Read Blogs for Developers - P1

To become a successful developer in such a competitive industry, you need to enrich not only your knowledge but also your mindsets to your job and social relationships. In this post, I will introduce top must-read blogs to become more specialized and have more soft skills for a promising developer career path.

So now let’s hesitate no more and get started!

Continue reading "Top Must-Read Blogs for Developers - P1"

What is a VPS Web Hosting Control Panel

What is a VPS Web Hosting Control Panel?

Virtual Private Server (VPS) hosting may be expensive compared to shared hosting but offers greater flexibility. These plans are a web developer’s dream come true, customizable in every way, from Operating systems (OS) to specific applications and frameworks deployed.

Yet this flexibility comes at the cost of VPS hosting requiring more technical skill to handle. To overcome this, we look towards the web hosting control panel, which can ease many tasks significantly.

Continue reading "What is a VPS Web Hosting Control Panel?"

Methods of removing unwanted meta boxes in your website.

How to Remove Unwanted Meta Boxes in WordPress

In the post editor or page editor, even admin dashboard, there are different meta boxes available. Perhaps, some of them are unused and you want to remove them to make your working screen clearer. It helps you to concentrate on the main contents better. Let’s learn how to remove unwanted meta boxes in WordPress.

You can use code or plugin as follows.

Continue reading "How to Remove Unwanted Meta Boxes in WordPress"

MB.Banner-General-bottom