{"id":928,"date":"2025-03-24T14:28:03","date_gmt":"2025-03-24T14:28:03","guid":{"rendered":"https:\/\/wpgeodirectory.com\/documentation\/article\/create-a-custom-input-field\/"},"modified":"2025-04-03T15:24:23","modified_gmt":"2025-04-03T14:24:23","slug":"create-a-custom-input-field","status":"publish","type":"gd_place","link":"https:\/\/wpgeodirectory.com\/documentation\/article\/code-snippets\/create-a-custom-input-field\/","title":{"rendered":"Create a custom input field"},"content":{"rendered":"\n<p>\n\tYou can add your own custom field types to GD and have then output as you wish.&nbsp; The below example adds a &#8220;date range&#8221; input field.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Add the field to the custom field settings<\/h3>\n\n\n\n<p>\n\tThe below code will add the field to the custom field settings so that you can add it to your add listing page.&nbsp; The &#8220;field_type&#8221; is the custom key that we will use for other hooks, in this case it is: <strong>daterange<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-php\">add_filter(&#039;geodir_custom_fields_custom&#039;,&#039;_my_gd_custom_field_date_range&#039;,10,2);\nfunction _my_gd_custom_field_date_range($custom_fields, $post_type ){\n\t\n\t\/\/ Date range\n\t$custom_fields&#091;&#039;date_range&#039;&#093; = array( \/\/ The key value should be unique and not contain any spaces.\n\t\t&#039;field_type&#039;  =&gt; &#039;daterange&#039;, \/\/ this is our new field type\n\t\t&#039;class&#039;       =&gt; &#039;gd-date-range&#039;,\n\t\t&#039;icon&#039;        =&gt; &#039;fas fa-calendar-alt&#039;,\n\t\t&#039;name&#039;        =&gt; __( &#039;Date Range&#039;, &#039;geodirectory&#039; ),\n\t\t&#039;description&#039; =&gt; __( &#039;Adds a date range input&#039;, &#039;geodirectory&#039; ),\n\t\t&#039;defaults&#039;    =&gt; array(\n\t\t\t&#039;data_type&#039;          =&gt; &#039;TEXT&#039;,\n\t\t\t&#039;admin_title&#039;        =&gt; &#039;Date range&#039;,\n\t\t\t&#039;frontend_title&#039;     =&gt; &#039;Dates&#039;,\n\t\t\t&#039;frontend_desc&#039;      =&gt; &#039;Enter the start and end dates.&#039;,\n\t\t\t&#039;htmlvar_name&#039;       =&gt; &#039;date_range&#039;,\n\t\t\t&#039;is_active&#039;          =&gt; true,\n\t\t\t&#039;for_admin_use&#039;      =&gt; false,\n\t\t\t&#039;default_value&#039;      =&gt; &#039;&#039;,\n\t\t\t&#039;show_in&#039;            =&gt; &#039;&#091;detail&#093;&#039;,\n\t\t\t&#039;is_required&#039;        =&gt; false,\n\t\t\t&#039;option_values&#039;      =&gt; &#039;&#039;,\n\t\t\t&#039;validation_pattern&#039; =&gt; &#039;&#039;,\n\t\t\t&#039;validation_msg&#039;     =&gt; &#039;&#039;,\n\t\t\t&#039;required_msg&#039;       =&gt; &#039;&#039;,\n\t\t\t&#039;field_icon&#039;         =&gt; &#039;fas fa-calendar-alt&#039;,\n\t\t\t&#039;css_class&#039;          =&gt; &#039;&#039;,\n\t\t\t&#039;cat_sort&#039;           =&gt; false,\n\t\t\t&#039;cat_filter&#039;         =&gt; false,\n\t\t\t\t\n\t\t)\n\t);\n\t\n\treturn $custom_fields;\n}\n<\/code><\/pre>\n\n\n\n<p>\n\tIt will then show in your Places &gt; Settings &gt; Custom Fields settings.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/wpgeodirectory.com\/documentation\/wp-content\/uploads\/2025\/03\/file-2h75IwNe4B.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Add the field input code<\/h3>\n\n\n\n<p>\n\tFor it to appear in the add listing page we need to tell the system what type of input we should show, if we simply wanted a text input we could add a single line such as:&nbsp; <em>add_filter(&#8216;geodir_custom_field_input_<strong>daterange<\/strong>&#8216;,&#8217;geodir_cfi_text<\/em><em>&#8216;,10,2);&nbsp;&nbsp;<\/em><br>\n\tThe Standard GD input function &#8220;geodir_cfi_text&#8221; would deal with the type of input, you can find all the default input types in this file: <a href=\"https:\/\/github.com\/AyeCode\/geodirectory\/blob\/master\/includes\/custom-fields\/input-functions-aui.php\">https:\/\/github.com\/AyeCode\/geodirectory\/blob\/master\/includes\/custom-fields\/input-functions-aui.php<\/a><\/p>\n\n\n\n<p>\n\tIn our case we want to setup a new type of input that includes a date range, we can save some time by copying the geodir_cfi_datepicker function and renaming it.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-php\">add_filter(&#039;geodir_custom_field_input_daterange&#039;,&#039;_my_geodir_cfi_daterange&#039;,10,2);\n\n\n\/**\n * Get the html input for the custom field: daterange\n *\n * @param string $html The html to be filtered.\n * @param array $cf The custom field array details.\n * @since 1.6.6\n *\n * @return string The html to output for the custom field.\n *\/\nfunction _my_geodir_cfi_daterange($html,$cf){\n\n\n    $html_var = $cf&#091;&#039;htmlvar_name&#039;&#093;;\n\n\n    \/\/ Check if there is a custom field specific filter.\n    if(has_filter(&quot;geodir_custom_field_input_datepicker_{$html_var}&quot;)){\n        \/**\n         * Filter the datepicker html by individual custom field.\n         *\n         * @param string $html The html to filter.\n         * @param array $cf The custom field array.\n         * @since 1.6.6\n         *\/\n        $html = apply_filters(&quot;geodir_custom_field_input_datepicker_{$html_var}&quot;,$html,$cf);\n    }\n\n\n    \/\/ If no html then we run the standard output.\n    if(empty($html)) {\n        global $geodir_label_type;\n\n\n        $extra_attributes = array();\n        $title = &#039;&#039;;\n        $value = geodir_get_cf_value($cf);\n\n\n        $name = $cf&#091;&#039;name&#039;&#093;;\n        $extra_fields = ! empty( $cf&#091;&#039;extra_fields&#039;&#093; ) ? maybe_unserialize( $cf&#091;&#039;extra_fields&#039;&#093; ) : NULL;\n        $date_format = ! empty( $extra_fields&#091;&#039;date_format&#039;&#093; ) ? $extra_fields&#091;&#039;date_format&#039;&#093; : &#039;yy-mm-dd&#039;;\n        $jquery_date_format = $date_format;\n\n\n        \/\/ Check if we need to change the format or not\n        $date_format_len = strlen( str_replace( &#039; &#039;, &#039;&#039;, $date_format ) );\n\n\n        \/\/ If greater then 5 then it&#039;s the old style format.\n        if ( $date_format_len &gt; 5 ) {\n            $search = array( &#039;dd&#039;, &#039;d&#039;, &#039;DD&#039;, &#039;mm&#039;, &#039;m&#039;, &#039;MM&#039;, &#039;yy&#039; ); \/\/ jQuery UI datepicker format.\n            $replace = array( &#039;d&#039;, &#039;j&#039;, &#039;l&#039;, &#039;m&#039;, &#039;n&#039;, &#039;F&#039;, &#039;Y&#039; ); \/\/ PHP date format\n\n\n            $date_format = str_replace( $search, $replace, $date_format );\n        } else {\n            $jquery_date_format = geodir_date_format_php_to_aui( $jquery_date_format );\n        }\n\n\n        if ( $value == &#039;0000-00-00&#039; ) {\n            $value = &#039;&#039;; \/\/ If date not set, then mark it empty.\n        }\n\n\n        \/\/validation\n        if(isset($cf&#091;&#039;validation_pattern&#039;&#093;) &amp;&amp; $cf&#091;&#039;validation_pattern&#039;&#093;){\n            $extra_attributes&#091;&#039;pattern&#039;&#093; = $cf&#091;&#039;validation_pattern&#039;&#093;;\n        }\n\n\n        \/\/ validation message\n        if(isset($cf&#091;&#039;validation_msg&#039;&#093;) &amp;&amp; $cf&#091;&#039;validation_msg&#039;&#093;){\n            $title = $cf&#091;&#039;validation_msg&#039;&#093;;\n        }\n\n\n        \/\/ field type (used for validation)\n        $extra_attributes&#091;&#039;field_type&#039;&#093; = $cf&#091;&#039;type&#039;&#093;;\n\n\n        \/\/ flatpickr attributes\n        $extra_attributes&#091;&#039;data-alt-input&#039;&#093; = &#039;true&#039;;\n        $extra_attributes&#091;&#039;data-alt-format&#039;&#093; = $date_format;\n        $extra_attributes&#091;&#039;data-date-format&#039;&#093; = &#039;Y-m-d&#039;;\n        $extra_attributes&#091;&#039;data-mode&#039;&#093; = &#039;range&#039;;\n\n\n        \/\/ minDate \/ maxDate\n        if ( ! empty( $extra_fields&#091;&#039;date_range&#039;&#093; ) ) {\n            $year_range = geodir_input_parse_year_range( $extra_fields&#091;&#039;date_range&#039;&#093; );\n\n\n            \/\/ minDate\n            if ( ! empty( $year_range&#091;&#039;min_year&#039;&#093; ) ) {\n                $extra_attributes&#091;&#039;data-min-date&#039;&#093; = $year_range&#091;&#039;min_year&#039;&#093; . &#039;-01-01&#039;;\n            }\n\n\n            \/\/ maxDate\n            if ( ! empty( $year_range&#091;&#039;max_year&#039;&#093; ) ) {\n                $extra_attributes&#091;&#039;data-max-date&#039;&#093; = $year_range&#091;&#039;max_year&#039;&#093; . &#039;-12-31&#039;;\n            }\n        }\n\n\n        \/**\n         * Filter datepicker field extra attributes.\n         *\n         * @since 2.1.1.11\n         *\n         * @param array $extra_attributes Field attributes.\n         * @param array $cf The custom field array.\n         *\/\n        $extra_attributes = apply_filters( &#039;geodir_cfi_daterange_extra_attrs&#039;, $extra_attributes, $cf );\n\n\n        \/\/ required\n        $required = !empty($cf&#091;&#039;is_required&#039;&#093;) ? &#039; &lt;span class=&quot;text-danger&quot;&gt;*&lt;\/span&gt;&#039; : &#039;&#039;;\n\n\n        \/\/ admin only\n        $admin_only = geodir_cfi_admin_only($cf);\n\n\n        $conditional_attrs = geodir_conditional_field_attrs( $cf );\n\n\n        $html = aui()-&gt;input(\n            array(\n                &#039;id&#039;                =&gt; $cf&#091;&#039;name&#039;&#093;,\n                &#039;name&#039;              =&gt; $cf&#091;&#039;name&#039;&#093;,\n                &#039;required&#039;          =&gt; !empty($cf&#091;&#039;is_required&#039;&#093;) ? true : false,\n                &#039;label&#039;              =&gt; __($cf&#091;&#039;frontend_title&#039;&#093;, &#039;geodirectory&#039;).$admin_only . $required,\n                &#039;label_show&#039;       =&gt; true,\n                &#039;label_type&#039;       =&gt; !empty($geodir_label_type) ? $geodir_label_type : &#039;horizontal&#039;,\n                &#039;type&#039;              =&gt; &#039;datepicker&#039;,\n                &#039;title&#039;             =&gt;  $title,\n                &#039;placeholder&#039;       =&gt; esc_html__( $cf&#091;&#039;placeholder_value&#039;&#093;, &#039;geodirectory&#039;),\n                &#039;class&#039;             =&gt; &#039;&#039;,\n                &#039;value&#039;             =&gt; $value, \/\/ esc_attr(stripslashes($value))\n                &#039;help_text&#039;         =&gt; __($cf&#091;&#039;desc&#039;&#093;, &#039;geodirectory&#039;),\n                &#039;extra_attributes&#039;  =&gt; $extra_attributes,\n                &#039;wrap_attributes&#039;   =&gt; $conditional_attrs\n            )\n        );\n\n\n    }\n\n\n    return $html;\n}\n<\/code><\/pre>\n\n\n\n<p>\n\tThis will then show on the add listing page.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/wpgeodirectory.com\/documentation\/wp-content\/uploads\/2025\/03\/file-mcB70y2qRF.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Output the custom field value<\/h3>\n\n\n\n<p>\n\tLastly, we need to tell it how it should be output, in this case we can use a default field such as a text field output.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-php\">add_filter(&#039;geodir_custom_field_output_daterange&#039;,&#039;geodir_cf_text&#039;,10,5);<\/code><\/pre>\n\n\n\n<p><br>The default GD function &#8220;geodir_cf_text&#8221; will output the value as simple text.\u00a0 If we wanted it to output something more than simple text or in a different format we could add a custom function.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/wpgeodirectory.com\/documentation\/wp-content\/uploads\/2025\/03\/file-LGosljxrZW.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can add your own custom field types to GD and have then output as you wish.&nbsp; The below example adds a &#8220;date range&#8221; input field. Add the field to the custom field settings The below code will add the field to the custom field settings so that you can add it to your add [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"article\/tags":[],"article\/categories":[211,432,433],"class_list":["post-928","gd_place","type-gd_place","status-publish","hentry","gd_placecategory-tips-tricks-more","gd_placecategory-how-tos","gd_placecategory-code-snippets"],"_links":{"self":[{"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/article\/928","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/types\/gd_place"}],"author":[{"embeddable":true,"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/comments?post=928"}],"version-history":[{"count":0,"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/article\/928\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/media?parent=928"}],"wp:term":[{"taxonomy":"gd_place_tags","embeddable":true,"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/article\/tags?post=928"},{"taxonomy":"gd_placecategory","embeddable":true,"href":"https:\/\/wpgeodirectory.com\/documentation\/wp-json\/wp\/v2\/article\/categories?post=928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}