HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/fire-tech/fire-tech.nl/resources/views/kms/attributes/autocompleteInput.blade.php
<div class="entity-attribute entity-attribute-autocomplete-combo-box {{$attribute->getStyleClass()}}">
    {!! Form::label($attribute->getKey(), $attribute->getLabelText()) !!}

    @if($attribute->getReadOnly())
        <div class="content">
            <ul>
                @foreach($attribute->getItems() as $selectOptionsModel)
                    @foreach(explode(',', $attribute->getValue()) as $currentItemId)
                        @if($currentItemId == $selectOptionsModel->getValue())
                            <li>{{$selectOptionsModel->getHtmlContent()}}</li>
                        @endif
                    @endforeach()
                @endforeach
            </ul>
        </div>
        {!! Form::hidden($attribute->getKey(), $attribute->getValue()) !!}
    @else
        <div class="ui-widget">
            <input id="{{$attribute->getKey()}}-fake"
                   placeholder=" @lang('kms/global.search2') {{$attribute->getLabelText()}}">
            <span class="dropdown" id="{{$attribute->getKey()}}-open"></span>
            <input type="hidden" id="{{$attribute->getKey()}}" name="{{$attribute->getKey()}}" value="">
        </div>
        <div class="items" id="{{$attribute->getKey()}}_items">

        </div>
        @if($attribute->getExplanation())<span class="explanation">{!! $attribute->getExplanation() !!} </span> @endif

        <script>
            $(function () {
                let controllerName = "{{$attribute->getKey()}}_controller";

                window[controllerName] = {
                    attributeKey: "{{$attribute->getKey()}}",

                    /**Select all elements for easy access later on**/
                    input: '',
                    openbutton: '',
                    autoCompleteSelectField: '',
                    itemsWrapper: '',
                    autoSaveUrl: "{{ $attribute->getAutoSaveUrl() }}",
                    maxItemsToSelect: {{ $attribute->getMaxItemsToSelect() }},
                    listenersEnabled: true,

                    /** The dataset for the autocomplete. Just an array of objects containing id and value properties**/
                    dataSet: [
                            @foreach($attribute->getItems() as $selectOptionModel)
                        {
                            "id": "{{$selectOptionModel->getValue()}}",
                            "value": "{!! $selectOptionModel->getHtmlContent() !!}",
                        }@if(!$loop->last),@endif
                        @endforeach()
                    ],

                    initialize: function () {
                        this.input = document.getElementById(this.attributeKey);
                        this.openbutton = document.getElementById(this.attributeKey + "-open");
                        this.autoCompleteSelectField = document.getElementById(this.attributeKey + "-fake");
                        this.itemsWrapper = document.getElementById("{{$attribute->getKey()}}_items");

                        this.makeAutoCompleteInput();
                        this.addItems();
                        this.updateRealInput();
                        this.enableListeners(true);
                        this.enableAutoCompleteOpenButton();
                    },

                    addItems: function()
                    {
                        let valuesFromAttribute = "{{$attribute->getValue() != '' ? $attribute->getValue() : $attribute->getDefaultValue()}}".split(',');
                        {{--console.log('{{$attribute->gedDefaultValue()}}');--}}
                                {{--console.log(valuesFromAttribute);--}}
                            for (let idFromAttribute of valuesFromAttribute) {
                            for (let item of this.dataSet) {
                                if (item.id === idFromAttribute) {
                                    this.addItem(item.id, item.value);
                                    break;
                                }
                            }
                        }
                    },

                    /**
                     * Makes the fake input field and autocomplete input field.
                     * Focus method is triggered when you hover over items in the menu
                     * select method is triggered when you click an item in the list.
                     */
                    makeAutoCompleteInput: function () {
                        let self = this;

                        $("#{{$attribute->getKey()}}-fake").autocomplete({
                            source: this.dataSet,
                            minLength: 0,

                            focus: function (event, ui) {
                                return false;
                            },
                            select: function (event, ui) {
                                $(this.autoCompleteSelectField).val("");
                                self.addItem(ui.item.id, ui.item.value);
                                self.updateRealInput();
                                self.autosaveIfNeeded();
                                self.enableListeners(true);
                                return false;
                            },
                        });
                    },

                    /**
                     * Make sure we can open the autocomplete field dropdown with the open button
                     */
                    enableAutoCompleteOpenButton() {
                        this.openbutton.addEventListener('click', (event) => {
                            $(this.autoCompleteSelectField).autocomplete("search", "");
                        });
                    },

                    /**
                     * Adds a span tag containing the value given and the data-id property set to id given to
                     * the p tag with class items.
                     */
                    addItem: function (id, value) {
                        let self = this;

                        if(this.itemsCount() > self.maxItemsToSelect) return;


                        let itemTemplate = `<p class="item" data-id="${id}">${value}</p>`;

                        let parser = new DOMParser();
                        let document = parser.parseFromString(itemTemplate, 'text/html');
                        let itemElement = document.body.firstChild;

                        itemElement.addEventListener('click', (function (itemToRemove) {
                            return () => {
                                if(!self.listenersEnabled) return;
                                self.removeItem(itemToRemove);
                            }
                        })(id));

                        this.itemsWrapper.appendChild(itemElement);
                    },

                    itemsCount: function()
                    {
                        return this.itemsWrapper.childNodes.length;
                    },

                    /**
                     * Iterates over the child elements of the p element with class items and removes the element that has
                     * data-id set to the specified id. Then calls updateRealInput to update the hidden input
                     */
                    removeItem: function (id) {
                        let items = this.itemsWrapper.children;
                        for (let item of items) {
                            if (item.dataset.id === id) {
                                this.itemsWrapper.removeChild(item);
                                break;
                            }
                        }
                        this.updateRealInput();
                        this.autosaveIfNeeded();
                    },

                    /**
                     * Iterates over the child elements of the p element with class items and concatenates their data-id
                     * values into a string. After that it sets the hidden input with the id string
                     */
                    updateRealInput: function () {
                        let ids = [];
                        let items = this.itemsWrapper.children;
                        for (let item of items) {
                            ids[ids.length] = item.dataset.id;
                        }
                        let idString = ids.join(',');

                        this.input.setAttribute('value', idString);
                    },

                    autosaveIfNeeded: function () {
                        if (!this.autoSaveUrl) return;
                        let itemIds = this.input.getAttribute('value');
                        let self = this;

                        $.ajax({
                            type: "POST",
                            url: this.autoSaveUrl,
                            data: {
                                'itemIds': itemIds,
                            },
                            success: function (response, textStatus, xhr) {
                                if (xhr.status === 200) {
                                    console.log('autosave successfull to url: ' + self.autoSaveUrl)
                                } else {
                                    console.error('autosave failure to url (no code 200): ' + self.autoSaveUrl + '');
                                    console.error(response)
                                }
                            },
                            error: function (message) {
                                console.error('autosave failure to url: ' + self.autoSaveUrl + '');
                                console.error(message)
                            },
                            headers: {
                                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                            },
                            dataType: 'json'
                        });
                    },

                    enableListeners: function (enable) {
                        let self = this;
                        this.listenersEnabled = enable;

                        let length = this.itemsWrapper.children.length;

                        //Add / remove listeners to items
                        for (let i = 0; i < length; i++) {
                            let item = this.itemsWrapper.children[i];
                            let id = item.dataset.id;

                            item.classList.remove('readonly');
                            this.autoCompleteSelectField.classList.remove('hidden');

                            if(!enable) {
                                item.classList.add('readonly');
                                this.autoCompleteSelectField.classList.add('hidden');
                                this.openbutton.classList.add('hidden');
                            }
                        }
                    },
                };

                window[controllerName].initialize();
            });
        </script>
    @endif
</div>