Skip to content

Instantly share code, notes, and snippets.

@alex-authlab
Last active October 20, 2020 16:54
Show Gist options
  • Save alex-authlab/85d4fda959acc87915b5e6eee6db3048 to your computer and use it in GitHub Desktop.
Save alex-authlab/85d4fda959acc87915b5e6eee6db3048 to your computer and use it in GitHub Desktop.
<?php
// ** Fluent Form custom input component : Show suggestion from wp post titles
// 1. Paste this in your theme function.php file or you can
// create a new file in active theme directory and include the file
if (!defined('ABSPATH')) {
exit;
}
use \FluentForm\App\Services\FormBuilder\BaseFieldManager;
use \FluentForm\Framework\Helpers\ArrayHelper;
class PostDataSuggestion extends BaseFieldManager
{
public function __construct()
{
parent::__construct(
'suggestionField',
'Post Data Suggestion',
['suggestion', 'dropdown', 'post data'],
'general'
);
}
function getComponent()
{
return [
'index' => 15,
'element' => $this->key,
'attributes' => [
'name' => $this->key,
'class' => '',
'value' => '',
'placeholder' => __('Dropdown Suggestion From Post Data', 'fluentformpro')
],
'settings' => [
'container_class' => '',
'placeholder' => '',
'post_type' => '',
'ignore_unmatched_data' => 'no',
'label' => $this->title,
'label_placement' => '',
'help_message' => '',
'admin_field_label' => '',
'validation_rules' => [
'required' => [
'value' => false,
'message' => __('This field is required', 'fluentformpro'),
]
],
'conditional_logics' => []
],
'editor_options' => [
'title' => $this->title . ' Field',
'icon_class' => 'el-icon-connection',
'template' => 'inputText'
],
];
}
public function getGeneralEditorElements()
{
return [
'label',
'admin_field_label',
'placeholder',
'value',
'label_placement',
'validation_rules',
];
}
public function getPostTypes()
{
$args = array(
'public' => true,
// 'publicly_queryable' =>true
);
$post_types = get_post_types( $args, 'objects' );
$temp = [];
foreach ( $post_types as $post_type ) {
$temp[]= [
"label" => $post_type->name,
"value" => $post_type->name,
];
}
wp_reset_postdata();
return $temp;
}
public function getPostData($data)
{
$post_type = ArrayHelper::get($data, 'settings.post_type');
$args = array(
'numberposts' => -1, // -1 is for all
'post_type' => $post_type, // or 'post', 'page'
'orderby' => 'title', // or 'date', 'rand'
'order' => 'ASC', // or 'DESC'
);
$myposts = get_posts($args);
$temp = [];
if($myposts)
foreach ($myposts as $mypost){
$temp[]= $mypost->post_title;
}
wp_reset_postdata();
return $temp;
}
public function generalEditorElement()
{
return [
'post_type' => [
'template' => 'select',
'label' => 'Select a Post Type',
'help_text' => 'Show suggestion from post title data',
'options' => $this->getPostTypes()
],
'ignore_unmatched_data' =>[
'template' => 'radio',
'label' => 'Ignore Unmacthed Data',
'help_text' => 'Text that is not in the dropdown will be ignored, value must match with a suggestion item',
'options' => [
[
'label' => 'Yes',
'value' => 'yes'
],
[
'label' => 'No',
'value' => 'no'
]
]
]
];
}
public function render($data, $form)
{
$elementName = $data['element'];
$data = apply_filters('fluenform_rendering_field_data_' . $elementName, $data, $form);
$data['attributes']['class'] = @trim(
'ff-el-form-control ff-el-custom-alex ' . $data['attributes']['class']
);
$data['attributes']['id'] = $this->makeElementId($data, $form);
if ($tabIndex = \FluentForm\App\Helpers\Helper::getNextTabIndex()) {
$data['attributes']['tabindex'] = $tabIndex;
}
$style ='<style>.ff-autocomplete {
position: relative;
display: inline-block;
}
.ff-autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
}
.ff-autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.ff-autocomplete-items div:hover {
background-color: #e9e9e9;
}
.ff-autocomplete-active {
background-color: #409EFF!important ;
color: #ffffff;
}</style>';
$elMarkup = $style."<div class='ff-autocomplete' style='width:100%;'><input " . $this->buildAttributes($data['attributes'], $form) . "></div>";
$this->pushScripts($data, $form);
$html = $this->buildElementMarkup($elMarkup, $data, $form);
echo apply_filters('fluenform_rendering_field_html_' . $elementName, $html, $data, $form);
}
private function pushScripts($data, $form)
{
// We can add assets for this field
add_action('wp_footer', function () use ($data, $form) {
?>
<script>
function ff_autocomplete(inp, arr) {
/*the autocomplete function takes two arguments,
the text field element and an array of possible autocompleted values:*/
var currentFocus;
/*execute a function when someone writes in the text field:*/
inp.addEventListener("input", function(e) {
var a, b, i, val = this.value;
/*close any already open lists of autocompleted values*/
closeAllLists();
if (!val) { return false;}
currentFocus = -1;
/*create a DIV element that will contain the items (values):*/
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "ff-autocomplete-items");
/*append the DIV element as a child of the autocomplete container:*/
this.parentNode.appendChild(a);
/*for each item in the array...*/
for (i = 0; i < arr.length; i++) {
/*check if the item starts with the same letters as the text field value:*/
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
/*create a DIV element for each matching element:*/
b = document.createElement("DIV");
/*make the matching letters bold:*/
b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
b.innerHTML += arr[i].substr(val.length);
/*insert a input field that will hold the current array item's value:*/
b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
/*execute a function when someone clicks on the item value (DIV element):*/
b.addEventListener("click", function(e) {
/*insert the value for the autocomplete text field:*/
inp.value = this.getElementsByTagName("input")[0].value;
/*close the list of autocompleted values,
(or any other open lists of autocompleted values:*/
closeAllLists();
});
a.appendChild(b);
}
}
});
inp.addEventListener("blur", function(e) {
let ingnoreData = '<?php echo ArrayHelper::get($data, 'settings.ignore_unmatched_data'); ?>'
if(ingnoreData ==='yes'){
if(!arr.indexOf(jQuery(this).val()) !== -1){
jQuery(this).val(' ');
}
}
});
/*execute a function presses a key on the keyboard:*/
inp.addEventListener("keydown", function(e) {
var x = document.getElementById(this.id + "autocomplete-list");
if (x) x = x.getElementsByTagName("div");
if (e.keyCode == 40) {
/*If the arrow DOWN key is pressed,
increase the currentFocus variable:*/
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { //up
/*If the arrow UP key is pressed,
decrease the currentFocus variable:*/
currentFocus--;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 13) {
/*If the ENTER key is pressed, prevent the form from being submitted,*/
e.preventDefault();
if (currentFocus > -1) {
/*and simulate a click on the "active" item:*/
if (x) x[currentFocus].click();
}
}
});
function addActive(x) {
/*a function to classify an item as "active":*/
if (!x) return false;
/*start by removing the "active" class on all items:*/
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
/*add class "autocomplete-active":*/
x[currentFocus].classList.add("ff-autocomplete-active");
}
function removeActive(x) {
/*a function to remove the "active" class from all autocomplete items:*/
for (var i = 0; i < x.length; i++) {
x[i].classList.remove("ff-autocomplete-active");
}
}
function closeAllLists(elmnt) {
/*close all autocomplete lists in the document,
except the one passed as an argument:*/
var x = document.getElementsByClassName("ff-autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt != x[i] && elmnt != inp) {
x[i].parentNode.removeChild(x[i]);
}
}
}
/* when someone clicks in the document:*/
document.addEventListener("click", function (e) {
closeAllLists(e.target);
});
}
/*An array containing all the data:*/
var postDatas = <?php echo json_encode($this->getPostData($data)); ?> ;
/*initiate the autocomplete function on the element, and pass along the data*/
ff_autocomplete(document.getElementById("<?php echo $data['attributes']['id']?>"), postDatas);
</script>
<?php
}, 9999);
}
}
add_action('init', function () {
new PostDataSuggestion();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment