Jquery Selectize Add "Clear All" link at the top of options from Ajax
Asked Answered
B

5

9

I am using Jquery's Selectize tagging library which works well for me so far.

Below is the code I have used.

Javascript Code:

$('#q').selectize({
    plugins: ['remove_button'],
    valueField: 'address',
    labelField: 'address',
    searchField: 'address',                 
    create: true,    
    render: {
        item: function(data, escape) {
            return '<div>' + escape(data.address) + '</div>';
        }

    },
    onChange: function(value) {
      $(".selectize-input input[placeholder]").attr("style", "width: 100%;");
    },
    load: function(query, callback) {
        if (!query.length) return callback();
        $.ajax({
            url:  base_url + '/search-property-autocomplete',
            type: 'POST',
            dataType: 'json',
            data: {
                q: query,

            },
            error: function() {
                callback();
            },
            success: function(res) {
                console.log(res.properties);
                callback(res.properties);
            }
        });
    }
});

PHP Code:

/* API for autocomplete list of properties */
Route::post('/search-property-autocomplete', function () {
    if (!empty(trim($_POST['q']))) {
        $search_term = trim($_POST['q']);


        // getting Suburb State and Postcode of the properties based on search 
        $query = Property::join('technobrave_suburbs_', function($join) {

                    $join->on('technobrave_properties_.suburb_id', '=', 'technobrave_suburbs_.id');
                });

        $query->join('technobrave_states_', function($join) {
            $join->on('technobrave_properties_.state_id', '=', 'technobrave_states_.id');
        });


        $query->select('technobrave_properties_.*', 'technobrave_suburbs_.suburb', 'technobrave_states_.state_name');

        $query->where(function($query) use ($search_term) {
            $query->where('technobrave_properties_.post_code', 'LIKE', '%' . $search_term . '%');
            $query->orwhere('technobrave_suburbs_.suburb', 'LIKE', '%' . $search_term . '%');
            $query->orwhere('technobrave_states_.state_name', 'LIKE', '%' . $search_term . '%');
        });
        $data = $query->take(8)->get(); // getting maximum 8 records only 

        if ($data) {
            foreach ($data as $current_record) {
                $result[] = array(
                    'address' => $current_record->suburb . ' ' . $current_record->state_name . ' ' . $current_record->post_code
                );
            }
        }
    } else {
        $result = [];
    }
    echo json_encode(array('properties' => $result));
});

As you can see in above code, I am using Ajax to populate data and getting records by calling my php function which is working absolutely fine.

Now, I want to append one item as a hyperlink at the top of my all the results something like Clear All which will come every time I search or type in my input-box.

And IF I click on Clear All link, the results which appended below should be cleared.

To use the clearoptions() event provided by Selectize, I have updated my create: in my JavaScript code with:

create: function(input, callback) {

    $.ajax({
        url:  base_url + '/search-property-autocomplete',
        type: 'POST',
        dataType: 'json',
        data: {
            q: query,

        },
        error: function() {
            callback();
        },
        success: function(res) {

            return callback({ address: "<a href='javascript:void(0)'>Clear All</a>" });

        }
    });


},

But it seems to be not working as I am unable to see my added option there. I am unable to see my Hyperlink after my results populate.

I already know using somethink like below code will remove my populated records after I search.

$('.my-hyperlink-custom-class').on('click', function() {
    control.clearOptions();
});

But I am stuck appending or pushing this new item to my code with the results I populate using Ajax.

Can someone guide me how can I achieve this.

Breath answered 13/9, 2017 at 12:3 Comment(0)
B
2

Thank you so much to all for help and support. And special thanks to @afeique's hint to implement this feature.

Here is the solution I eventually came up with.

$('#q').selectize({
    plugins: ['remove_button'],
    valueField: 'address',
    labelField: 'address',
    searchField: 'address',                 
    create: true,    
    render: {
        item: function(data, escape) {
            return '<div>' + escape(data.address) + '</div>';
        }

    },
    onChange: function(value) {
      $(".selectize-input input[placeholder]").attr("style", "width: 100%;");
    },
    load: function(query, callback) {
        if (!query.length) return callback();

        // Appending only if not exists 
        if($('.clearAllSuggestions').length == 0) {
            $(".selectize-dropdown").append('<a href="#" class="clearAllSuggestions">Clear All</a>');
        }
        $.ajax({
            url:  base_url + '/search-property-autocomplete',
            type: 'POST',
            dataType: 'json',
            data: {
                q: query,

            },
            error: function() {
                callback();
            },
            success: function(res) {
                console.log(res.properties);
                callback(res.properties);
            }
        });
    }
});


$('body').on('click', '.clearAllSuggestions', function() {

    var $select = $('#q').selectize({});
    var control = $select[0].selectize;
    control.clearCache('option');
    control.clearOptions();
    control.refreshOptions(true);
});

I modified my code a bit and put below code in my load event to append "Clear All" anchor tag in my suggestion tag options.

// Appending only if not exists 
        if($('.clearAllSuggestions').length == 0) {
            $(".selectize-dropdown").append('<a href="#" class="clearAllSuggestions">Clear All</a>');
        }

Then, I simply wanted to clear cache and options hence I put below code.

$('body').on('click', '.clearAllSuggestions', function() {

    var $select = $('#q').selectize({});
    var control = $select[0].selectize;
    control.clearCache('option');
    control.clearOptions();
    control.refreshOptions(true);
});

Hope this helps.

Breath answered 25/9, 2017 at 6:25 Comment(0)
C
4

Here is the script I wrote. This will change all the href attribute above the selected one with the javascript:; while the below one will remain the same.You can modify this as per your need.

$(".row").click(function(){
var present =  $(this).index();
console.log("present"+present)
 $(this).closest('.container').find('.row').each(function(index,element){
  console.log("eachindex"+$(this).index());
 	if($(this).index()>=present) {
  	
  }
  else {
  	$(this).attr("href","javascript:;");
  }
 })
 $(".row").each(function(){
 	$("#finalAttribute").append($(this).attr("href"));
 })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <a class="row row1" href="#1">
  R1
  </a>
  <br/>
    <a class="row row2" href="#2">
  R1
  </a>
    <br/>
    <a class="row row3" href="#3">
  R2
  </a>
    <br/>
    <a class="row row4" href="#4">
  R3
  </a>
    <br/>
          <a class="row row5" href="#5">
  R4
  </a>
    <br/>
</div>
<div id="finalAttribute">


</div>
Chlamydeous answered 18/9, 2017 at 4:44 Comment(0)
G
4

Can you try this method, I believe your issue is with DOM rendering and binding JS functions. since the element is not available on load, the element cannot by bind with javascript. below method will work.

$('body').on('click', '.my-hyperlink-custom-class', function() {
    control.clearOptions();
});

Here i have have bind the function to body, however im again checking if target element is .my-hyperlink-custom-class.

Granoff answered 24/9, 2017 at 23:37 Comment(0)
P
3

Forgive me, I don't have experience with Selectize but I did scan through their examples and noticed something that may be helpful:

$('#input-tags3').selectize({
    plugins: ['remove_button'],
    delimiter: ',',
    persist: false,
    create: function(input) {
        return {
            value: input,
            text: input
        }
    }
});

In this example, the create: has function prototype function(input) which only has one argument and no callback function. Your code is using the following prototype: create: function(input, callback). From the Selectize examples, I have only seen load: use function(input, callback).

I would suggest altering your create: to something along the lines of:

create: function(input) {
    // append "clear all" anchor to top of search div
    $("#searchDiv").append('<a href="#" class="clearAll">Clear All</a>')

    // perform autocomplete AJAX
    $.ajax({
        url:  base_url + '/search-property-autocomplete',
        type: 'POST',
        dataType: 'json',
        data: {
            q: query,

        },
        error: function() {
            // add text
            return input;
        },
        success: function(res) {
            // TODO: do something to display the autocomplete results
            // e.g. create a dropdown with autcomplete suggestions
            // TODO: handle user selecting one of the suggestions

            // add text
            return input;
        }
    });


},

and fill out the necessary TODOs to get the functionality you desire.

HTH

Pancratium answered 22/9, 2017 at 19:23 Comment(1)
Your Answer somehow helped me to solve or implement what I want. Hence I am selecting your answer to give bounty rewards. However, I provided my answer as final code if someone stuck to the same issue where I did. Thank you.Breath
S
3

What you are trying to achieve can be done a little differently. Using create callback will create new items that aren't in the initial list of options when you select the add ... option shown on top. This is not what you want.

Just try:

var $select = $('#q').selectize({
    plugins: ['remove_button'],
    valueField: 'address',
    labelField: 'address',
    searchField: 'address',                 
    create: false,
    score: function() { return function() { return 1; }; },
    render: {
        item: function(data, escape) {
            return '<div>' + escape(data.address) + '</div>';
        }

    },
    onChange: function(value) {

      if(value == 'Clear All') {
          var control = $select[0].selectize;
          control.clearOptions();
      }
    },
    load: function(query, callback) {
        if (!query.length) return callback();
        $.ajax({
            url: base_url + '/search-property-autocomplete',
            type: 'POST',
            dataType: 'json',
            data: {
                q: query,

            },
            error: function() {
                callback();
            },
            success: function(res) {
                // add the clear All option  on top.
                res.properties.unshift({address: "Clear All" });
                callback(res.properties);
            }
        });
    }
});

This adds an extra option and uses onChange event to clear options when selected.

Also note the score option, so that the default filtering is disabled.

Shallop answered 23/9, 2017 at 18:15 Comment(0)
B
2

Thank you so much to all for help and support. And special thanks to @afeique's hint to implement this feature.

Here is the solution I eventually came up with.

$('#q').selectize({
    plugins: ['remove_button'],
    valueField: 'address',
    labelField: 'address',
    searchField: 'address',                 
    create: true,    
    render: {
        item: function(data, escape) {
            return '<div>' + escape(data.address) + '</div>';
        }

    },
    onChange: function(value) {
      $(".selectize-input input[placeholder]").attr("style", "width: 100%;");
    },
    load: function(query, callback) {
        if (!query.length) return callback();

        // Appending only if not exists 
        if($('.clearAllSuggestions').length == 0) {
            $(".selectize-dropdown").append('<a href="#" class="clearAllSuggestions">Clear All</a>');
        }
        $.ajax({
            url:  base_url + '/search-property-autocomplete',
            type: 'POST',
            dataType: 'json',
            data: {
                q: query,

            },
            error: function() {
                callback();
            },
            success: function(res) {
                console.log(res.properties);
                callback(res.properties);
            }
        });
    }
});


$('body').on('click', '.clearAllSuggestions', function() {

    var $select = $('#q').selectize({});
    var control = $select[0].selectize;
    control.clearCache('option');
    control.clearOptions();
    control.refreshOptions(true);
});

I modified my code a bit and put below code in my load event to append "Clear All" anchor tag in my suggestion tag options.

// Appending only if not exists 
        if($('.clearAllSuggestions').length == 0) {
            $(".selectize-dropdown").append('<a href="#" class="clearAllSuggestions">Clear All</a>');
        }

Then, I simply wanted to clear cache and options hence I put below code.

$('body').on('click', '.clearAllSuggestions', function() {

    var $select = $('#q').selectize({});
    var control = $select[0].selectize;
    control.clearCache('option');
    control.clearOptions();
    control.refreshOptions(true);
});

Hope this helps.

Breath answered 25/9, 2017 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.