Simplistic way to Disable Dates on Ninja Forms datepicker using ACF Repeater from the Options Page

Note: Ninja Forms version 3.4.31 and above no longer uses PikaDate it was updated to Flatpickr

While working on a recent project I needed to disable specific dates on the date picker within Ninja Forms.

I kept running into Uncaught SyntaxError: Invalid or unexpected token error when using the disableDayFn function while following the date picker documentation. After testing on my client’s site for a few hours I had thought the documentation was outdated. It turns out I was wrong1.

Ninja Forms Setup

Finally I decided that maybe I should test on my local environment instead of a live website, so I spun up my local WordPress install, installed ninja forms, and imported a test form.

Then carefully coping over each piece of code from the documentation over one by one but this time instead I would not combine the two JS files but keep them separate. Not sure why but this seemed to have worked and resolved my SyntaxError for the disableDayFn.

So keep the scripts.js and customDatePicker.js separate.

After cleaning all the comments and removing the labels and enabled days functions I was left with this:

var customDatePickerStuff = Marionette.Object.extend( {
    initialize: function() {
        this.listenTo( Backbone.Radio.channel( 'pikaday' ), 'init', this.modifyDatepicker );	
    },
    modifyDatepicker: function( dateObject, fieldModel ) {
        dateObject.pikaday._o.disableDayFn = function( date ) {
            var disabledDays = ["2017-04-28", "2017-04-29", "2017-04-30"];
            if ( _.indexOf( disabledDays, moment( date ).format( "YYYY-MM-DD" ) ) !== –1 ) {
                return true;
            }
        }
    }
});
jQuery( document ).ready( function() {
	new customDatePickerStuff();
} );

1Update October 29th 2020:

Emailed Free Support and heres what they found

I figured out the syntax issue. It was missing a parenthesis around the ‘if’ statement. See the following code,
dateObject.pikaday._o.disableDayFn = function( date ) {
            var disabledDays = ["2020-10-29"];

            if ( (_.indexOf( disabledDays, moment( date ).format( "YYYY-MM-DD" ) ) ) !== -1 ) {
                return true;
            }
        }
Once you add the parenthesis it disables all days except for the 29th …. or whatever days you want disabled. Please let us know if you need anything else.

Step 1. Completed. ff..finally.

Setup ACF Options Page and repeater fields.

//ACF Options Page
if( function_exists('acf_add_options_page') ) {
	acf_add_options_page();
}

After updated the disabledDays array to more current/futures dates to test, the dates are disabled.

A good sign of progress.

During the ACF repeater field setup, you’ll need to match the date format to the disabledDays array above. So in the date subfield select the return format to custom and enter

Y-m-d

One step forward another step back

While going down another Google rabbit hole and open tabs hell, I decided to just search the ACF support forums (because I’m definitely not the only one who had had this question of getting ACF repeater values into a JavaScript file) and BOOM found like 2 articles [1][2].

Question: How do I pass ACF field values into a JavaScript file?
Answer: wp_localize_script

/*
 * Plugin Name: Ninja Forms – Datepicker Customizations
 */
add_filter( 'ninja_forms_enqueue_scripts', 'nf_datepicker_options' );
function nf_datepicker_options() {
	wp_enqueue_script( 'nf_datepicker_options', plugin_dir_url( __FILE__ ) . 'script.js', array( 'jquery' ), false, true );

	wp_register_script( 'nf_datepicker_options-custom', plugin_dir_url( __FILE__ ) . 'customDatePicker.js' );
	wp_localize_script( 'nf_datepicker_options-custom', 'acf_dates', array(
        'block_dates' => get_field("block_dates", 'option')
    ) );
	wp_enqueue_script( 'nf_datepicker_options-custom' );
}

Sounds nice and easy right?

It is actually is pretty easy. Just pass in the field names into wp_localize_script

wp_localize_script( 'nf_datepicker_options-custom', 'acf_data', array(
    'field_name' => get_field("field_name"),
    'field_type' => get_field("field_type", 'option') // if youre using the options page
) );

Inside the JS file, call the data:

console.log ( acf_data.field_name );
console.log ( acf_data.field_type );

So close yet so far.

First, move the disabledDays array out of the modifyDatepicker function and after a lot of console.logging, hard refreshes, clearing the browser cache and 1 final ‘quick’ google search on “convert nested objects to an array, javascript” and landing on stack overflow one final time, thanks internet! You’re really the one doing my job for me!

const array = acf_dates.block_dates;
var disabledDays = [].concat(...array.map(Object.values));
var customDatePickerStuff = Marionette.Object.extend( {
    initialize: function() {
        this.listenTo( Backbone.Radio.channel( 'pikaday' ), 'init', this.modifyDatepicker );	
    },
    modifyDatepicker: function( dateObject, fieldModel ) {
        dateObject.pikaday._o.disableDayFn = function( date ) {
            if ( _.indexOf( disabledDays, moment( date ).format( "YYYY-MM-DD" ) ) !== -1 ) {
                return true;
            }
        }
    }
});
jQuery( document ).ready( function() {
    new customDatePickerStuff();
} );

Hope this will help someone spend less time in front of the computer screen and more time outside maybe… leave a comment in the comments below.

Update November 24th 2020:

Recently updated Ninja Forms on the client’s site and all the hard work above came crashing down below is what Ninja Form Free Support said in an email

In the Ninja Forms version 3.4.31 and above the library for the Date field was updated to use the Flatpickr library. The developer documentation has not yet been updated for the Flatpickr at this time. While custom code is outside the scope of support that we’re able to help with, you can find documentation for Flatpickr here: https://flatpickr.js.org/

My 1st GTA 5 Machinima / Happy Trails

My 1st published design on Thingiverse

Simple clothes hanger connector hook that allows multiple hangers to hang off one another which helps saves space in the closet. Any suggestions, remixes, comments or tips are welcome.

How to Supercharge ACF Repeater Fields inside Divi Modules

Recently when working on a client’s website I needed to use the ACF repeater fields on a WordPress site that was built on Divi. After doing a quick google search and reading a few articles it seemed normal ACF fields on Divi’s modules work flawlessly but when it comes to the repeater fields there seem to be technical issues and after a search on ACF support, it looks like I was not the only one with the same problem.

So I’ve created a custom page template for the custom post type because how else am I going to get the repeater fields showing up on the page, I completed the page and nonetheless the client ends up asking for the content to be put into tabs. I initially thought of adding bootstrap for it’s tabbed featured and quickly remembered and realized that it may conflict with Divi and that Divi had its own built-in tab module.

Inserting Divi Modules into the templates

Instead of rebuilding the own page on a Divi, I decided to use the page template but somehow integrate the Divi tab module into my page template. So after a quick google search, I ended up on a post about how to integrate Divi section into a page template, so after skimming through the article I ended finding the piece of code I needed;

<?php echo do_shortcode('[et_pb_section global_module="198"][/et_pb_section]'); ?>

Using the Divi library you can create a section with any module and using the shortcode above you can insert into any page template you’ll need the module on.

With that, I created the tab module with a few test tabs and sure enough the module loaded onto the page where I had inserted the line of code, now to get the ACF repeater field working on the module.

In comes ACF Repeater

I know I needed PHP for the ACF repeater fields to work properly so from my older work I’ve learned using shortcodes to run code is a neat little trick and works almost everywhere in WordPress and could get anything done and it’s in the functions.php file so it can run PHP!

Using the WordPress shortcode API and ob_start(); I’ve created a simple solution to the problem with displaying ACF repeater fields in Divi modules.

Just place inside your functions.php file and add your ACF repeater fields coding inside, then add the shortcode (in this case [foobar]) to the Divi module

function foobar_func( $atts ){
ob_start();
//ACF fields here
return ob_get_clean();
}
add_shortcode( 'foobar', 'foobar_func' );

Let me know in the comments before if it works for you or if you have another way to add the ACF repeater fields to the Divi modules

2020 Facebook Cover Photo Template (PSD)

I’m always finding myself googling “Facebook Cover Photo Template” whenever I need to design a new Facebook cover photo for myself or a client of mine. There are tons of sites on this topic including this one, which I based my initial design off of. They do offer templates but behind a sign up wall. Well, here is my template you can feel free to use and modify.

2020 Facebook Cover Photo Template (PSD) 1 Download Template

Painless Solution for WooCommerce Cart Icon with Item Count on the Divi Theme

Today I was trying to look for how to add an item count to the shopping cart on the Divi theme, I couldn’t find exactly what I was looking for although I did manage to find a few examples on StackOverflow and other websites that work with woocommerce on other themes but on divi it did not work at all.

After searching the divi support forum and documentation I did manage to find a few articles that were exactly what I was looking for however the articles are for members only. Being a freelancer I may have to work with any themes or plugins my clients may have on their website as it was in this case.

So instead of contacting my client and going through email hell for my client and myself, I started taking a look into the header.php file in the Divi Theme – thankfully one of my first tasks when taking on the client was to create a child theme.

Searching for the Divi Item Count Solution

After looking for a minute I finally found what I was looking for and luckily it was a very simple change to display the item count on the shopping cart icon on the menu.

Painless Solution for WooCommerce Cart Icon with Item Count on the Divi Theme 2

First, you’ll need to copy the header.php file from the divi theme into your divi-child theme then on or around Line 285 you’ll find an array with:

'no_text' => true,

You’ll need to change the true to false

'no_text' => false,

Save the header.php file.

Making the change on the child theme is important so any future updates to the divi theme won’t overwrite any changes previously made.

After this small change, you’ll see the number of items next to the cart icon on the main navigation menu, you may have to style the icon and text a little bit, but for the most part its there.

Let me know if this worked out for you or you have another way around this in the comments below!

How to sort WooCommerce Products (2019)

Recently I was trying to sort some products on WooCommerce for one of my clients and ended up doing a quick little Google search. I found all the top search results were pretty outdated, most of the posts were from 2015. WooCommerce has been through a few updates since then and the process to sort the products on the shop page is different.

In WooCommerce 3.7 to sort the products on the shop page is super simple you  just have to go to:

Products > All Products > Sorting

Then you can drag and drop how you want the products to display on the shop page.

How to sort WooCommerce Products (2019) 3 How to sort WooCommerce Products (2019) 4

And thats it.

My First Crypto App

I’ve created a simple and nifty crypto market watch app for my Advanced JavaScript boot-camp course at HackerYou. Using the CoinCecko API I am pulling the top 3 crypto markets with the overall fear and greed index for Bitcoin. It has has the top losers and gainers for the top 10 markets as well as the top 100 markets.

My initial idea was for dividend stocks but I couldn’t find a good free financial api – the main goal of the app is to see the top losers for the day and make it easier to decide on buying the crypto-currency you’re watching.

Check it out here:
https://www.rickypoon.ca/crypto_app/

Upgrading Bootstrap 3 to Bootstrap 4 with a Shim JS

When I was looking to upgrade a few past projects that I built on Bootstrap v3 to the latest version of Bootstrap, I’ve found it not as easy as it should be. Upgrading to Font Awesome 5 gave me an idea which I found no results online; I did find that it was previously brought up on GitHub but it was turned down by developers for the lack of time.

So I went online looking if there was a simple solution created by someone else but found none, so I’ve decided to create my own.

Following a medium article Migration from Bootstrap 3 to Bootstrap 4 by Łukasz Holeczek I’ve wrote a quick script that would go through the DOM finding previous Bootstrap 3 classes and making changes to match Bootstrap 4 classes.

While it is definitely not perfect, it works pretty well for the few projects I’ve used it in. There are areas where it is needed to update the classes manually and a few things that could be improved on; such as the input groups prepends/appends.

Bootstrap Shim Input Groups

I am open to suggestions and curious to see what people think of it, if you would make use of something like this? Let me know with the comments below, feel free to use and modify the code any way you wish.

If you are looking to migrate Bootstrap 3 to 4, you can view the project here:
https://github.com/poonasor/bootstrap-v3-shim

Hello, this is a Robot calling..

Over the last week I’ve received a numerous of calls from a local 416/647 number and every time I pick up thinking it is someone of importance calling me and then I hear this;

“Hello, this is Julia calling, your business has been pre-approved for a business to hear more about this opportunity…”

It wasn’t until I was so sick of picking up either a silent call or a robo call from Julia that I finally decided and listen all the way though. And when I finally listened to robot Julia finish talking about my pre-approved business loan that I figured out I could have pressed 2 to be placed on the “Do not call list”. Personally, I don’t know how much I trust this “Do not Call” list but I pressed 2 anyway, hopefully robot Julia will stop calling.

I’m sure I am not the only one receiving robo calls or even those “CRA” scams trying to get me to buy iTunes or Amazon gift cards to pay off the money I owe to the government from back taxes. I’ve even received emails from a unknown person(s) that I’ve been caught on webcam “Self Abusing” myself and that if I don’t send 333 Euros in Bitcoin (BTC) to 1PGaSS3iew4EbS4vnb6iGDrYDiCyXqLXSD that video will be sent to my social and work contacts.

I knew this is a full on lie and scam since I have electrical taped over my webcam on my Macbook Pro. When I first got that email I’ve checked the BTC address and it had 0 activity and no transactions but as I am writing this post I checked again and it had received a total of 0.07034538 BTC worth $592.79CAD.

What I’ve noticed is that the surge of spam emails and robo calls starts after I purchase new domain names. The first time I’ve noticed this was when I brought a domain name for my brother and then afterwards I was getting a ton of emails from India asking about the new domain name and if I needed any assistant in building a website or if I need any SEO work for my new website. This is also the time I started getting those robo CRA scam calls and the email asking for bitcoin or he’ll share a video of me abusing myself. Now I understand why the domain privacy up sell is so important when buying a domain name and how hosting companies must be making a killing off this up-sell.

So what can you do to protect yourself and your privacy?

The most common option people do is not picking up from a number they don’t know and letting it go into voicemail, but that is really not a solid solution to this problem. What happens if you are waiting on a call for an job interview or a call from from a delivery? (Both in my case).

The worst part of this is that scammers use a method called ‘spoofing‘ where they use a local number so it looks like regular number. I have received calls I let go to voicemail only to call back and have the person on the other line tell me that they did not call me.

Here are some ways you can protect yourself from annoying robo calls

1. Register your number to the Do not Call list
Add your number if you had not done so already on Canada’s National Do Not Call List. It won’t solve all the calls but it helps reduce the number of calls.

Your number will be removed from telemarketing lists but if you are still getting calls you can file a complaint with the CTRC.

You can also forward spam texts to 7726 (or SPAM). This will report the SPAM number to your wireless provider, you will also receive a response thanking you for reporting it.

2. When buying a domain name, purchase domain privacy
Most hosting companies and domain name registrars offers a domain privacy up sell with the domain name, this protects your personal contact information on the whois database which can be crawled with bots for contact information such as emails and phone numbers

3. Don’t provide any personal information when speaking over the phone
When someone says they are from a company and starts asking for personal information, don’t tell them anything. Instead call the company directly and ask for whatever was being said, better yet go in person.

If you do answer a call and hear a recording such as “Hello, can you hear me?”, just hang up.

4. Download a Call Blocking App
You can also download a call blocking app which has a list of known spam and fraudulent number and will tell you if the number that is calling you is a known scammer. I’ve previously spoken with my wireless provider (Rogers) and they responded that they don’t currently offer service natively.

CTIA.org has a comprehensive list of robo blocking apps for Android, BlackBerry, iOS (Apple) and Windows.

The most popular ones available in Canada are: True Caller & Hiya

I’ve downloaded True Caller and I got to say the number of calls has dropped dramatically, I won’t say it has stopped 100% but I do see an definite improvement.

Bonus. Check HaveIBeenPwned.com to see if your email has been compromised
Visit HaveIBeenPwned.com and enter your email to see if your email has been compromised in any data breachs

31-10-2018 Update: CBC MARKETPLACE| Police raid Indian call centres linked to ‘CRA phone scam’ that have victimized Canadians