jQuery select2: duplicate tag getting recreated - javascript

I asked a question earlier today (jquery select2: error in getting data from php-mysql). However, I am trying to fix it and doing that now I am getting bit strange issue. I am not sure why it is happening like this.
Below is the JavaScript code.
<div class="form-group">
<label class="col-sm-4 control-label">Product Name</label>
<div class="col-sm-6">
<input type="hidden" id="tags" style="width: 300px"/>
</div>
</div>
<script type="text/javascript">
var lastResults = [];
$("#tags").select2({
multiple: true,
placeholder: "Please enter tags",
tokenSeparators: [","],
initSelection : function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
},
ajax: {
multiple: true,
url: "fetch.php",
dataType: "json",
type: "POST",
data: function(term) {
return {q: term};
},
results: function(data) {
return {results: data};
},
},
createSearchChoice: function (term) {
var text = term + (lastResults.some(function(r) { return r.text == term }) ? "" : " (new)");
return { id: term, text: text };
},
});
$('#tags').on("change", function(e){
if (e.added) {
if (/ \(new\)$/.test(e.added.text)) {
var response = confirm("Do you want to add the new tag "+e.added.id+"?");
if (response == true) {
alert("Will now send new tag to server: " + e.added.id);
/*
$.ajax({
type: "POST",
url: '/someurl&action=addTag',
data: {id: e.added.id, action: add},
error: function () {
alert("error");
}
});
*/
} else {
console.log("Removing the tag");
var selectedTags = $("#tags").select2("val");
var index = selectedTags.indexOf(e.added.id);
selectedTags.splice(index,1);
if (selectedTags.length == 0) {
$("#tags").select2("val","");
} else {
$("#tags").select2("val",selectedTags);
}
}
}
}
});
</script>
Here is the php code (fetch.php)
<?php
// connect to database
require('db.php');
// strip tags may not be the best method for your project to apply extra layer of security but fits needs for this tutorial
$search = strip_tags(trim($_GET['q']));
//$search='te';
// Do Prepared Query
$query = $mysqli->prepare("SELECT tid,tag FROM tag WHERE tag LIKE :search LIMIT 4");
// Add a wildcard search to the search variable
$query->execute(array(':search'=>"%".$search."%"));
// Do a quick fetchall on the results
$list = $query->fetchall(PDO::FETCH_ASSOC);
// Make sure we have a result
if(count($list) > 0){
foreach ($list as $key => $value) {
$data[] = array('id' => $value['tid'], 'text' => $value['tag']);
}
} else {
$data[] = array('id' => '0', 'text' => 'No Products Found');
}
// return the result in json
echo json_encode($data);
?>
select2 version is 3.5
Above code is able to send/receive request from database by using fetch.php.
Problem is in my database there are two records test & temp when I tag any one of them it create new tag.
It should work like this: if database have value then it won't create the new tag with same name.
Update

Tags need an id and a text. The issue you're facing is that your text doesn't match the id.
So, even if you write the same text, Select2 thinks the new text is a new option because the id don't match.
To solve your issue, you need to set the id with the same value as the text. Change the foreach of your fetch.php to the following:
foreach ($list as $key => $value) {
$data[] = array('id' => $value['tag'], 'text' => $value['tag']);
}
Update:
You also need to update the variable lastResults to avoid the duplication of tags with the same text. When you bind select2, you need to change the results property of ajax to this (based on this answer:
ajax: {
multiple: true,
url: "fetch.php",
dataType: "json",
type: "POST",
data: function(term) {
return {q: term};
},
results: function(data) {
lastResults = data.results;
return {results: data};
},
},
Note the lastResults = data.results;. Without this, the lastResults variable is always empty and, when the createSearchChoice function is executed, it will always return a new tag.

Finally it is working now. I would like to thanks #alex & #milz for their support.
Here is the full n final code. Now duplicate tags are not creating. However, i am working to add tag in database.
php/html file
<div class="form-group">
<label class="col-sm-4 control-label">Product Name</label>
<div class="col-sm-6">
<input type="hidden" id="tags" style="width: 300px"/>
</div>
</div>
<script type="text/javascript">
var lastResults = [];
$("#tags").select2({
multiple: true,
tags: true,
placeholder: "Please enter tags",
tokenSeparators: [',', ' '],//[","],
initSelection : function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
},
ajax: {
multiple: true,
url: "fetch.php",
dataType: 'json',
// type: "POST",
data: function(term,page) {
return {
term: term
};
},
results: function(data,page) {
lastResults = data;
return {results: data};
},
},
maximumSelectionSize: 3,
minimumInputLength: 3,
createSearchChoice: function(term) {
console.log($(this).attr('data'));
var text = term + (lastResults.some(function(r) {
console.log(r.text);
console.log(term);
return r.text == term
}) ? "" : " (new)");
return {
id: term,
text: text
};
},
});
$('#tags').on("change", function(e){
if (e.added) {
if (/ \(new\)$/.test(e.added.text)) {
var response = confirm("Do you want to add the new tag "+e.added.id+"?");
if (response == true) {
alert("Will now send new tag to server: " + e.added.id);
/*
$.ajax({
type: "POST",
url: '/someurl&action=addTag',
data: {id: e.added.id, action: add},
error: function () {
alert("error");
}
});
*/
} else {
console.log("Removing the tag");
var selectedTags = $("#tags").select2("val");
var index = selectedTags.indexOf(e.added.id);
selectedTags.splice(index,1);
if (selectedTags.length == 0) {
$("#tags").select2("val","");
} else {
$("#tags").select2("val",selectedTags);
}
}
}
}
});
</script>
Here is the php file to get the data from database.
fetch.php
<?php
// connect to database
require('db.php');
// strip tags may not be the best method for your project to apply extra layer of security but fits needs for this tutorial
//if(isset($_GET)){
$search = strip_tags(trim($_GET['term']));
// Do Prepared Query
$query = $mysqli->prepare("SELECT tid,tag FROM tag WHERE tag LIKE :search LIMIT 4");
// Add a wildcard search to the search variable
$query->execute(array(':search'=>"%".$search."%"));
$list = $query->fetchall(PDO::FETCH_ASSOC);
if(count($list) > 0){
foreach ($list as $key => $value) {
$data[] = array('id' => $value['tag'], 'text' => $value['tag']);
}
} else {
$data[] = array('id' => 'No Products Found', 'text' => 'No Products Found');
}
echo json_encode($data);
?>
It took lots of time. Almost 3 days. I hope it will save someone efforts.

Apply the changes as in the select2.min.js (v4.0.6-rc.1) code snippet below
section 1
c.on("results:select", function() {
var a = e.getHighlightedResults();
if (0 !== a.length) {
var c = b.GetData(a[0], "data");
"true" == a.attr("aria-selected") ? e.trigger("close", {}) : e.trigger("select", {
//custom select2 tagging
if(a.attr("aria-selected")){
c.id = c.id + 1;
}
e.trigger("select", {
data: c
})
//"true" == a.attr("aria-selected") ? e.trigger("close", {}) : e.trigger("select", {
// e.trigger("select", {
// data: c
// })
}
})
section 2
this.on("query", function(b) {
a.isOpen() || a.trigger("open", {}), this.dataAdapter.query(b, function(c) {
//custom select2 tagging
let searchInput = $(".select2-search__field").val();
searchInput = {results: [{id: searchInput, text: searchInput}]};
a.trigger("results:all", {
data: c,
data: searchInput,
query: b
})
})
})

Related

Select2 v.4xx Pagination for Infinite Scrolling Codeigniter 4

I tried the pagination feature for searching data using Select2 4.x, but I haven't been able to achieve it. Does anyone know how to do it on codeigniter 4 by including the CSRF token.
If the user performs a search it will display 20 lines, and return to do so with a scroll of 20 lines.
Can anyone help for my problem.
my template HTML:
<div class="form-group">
<select id="selectData" class="form-control" style="width: 100%;"></select>
</div>
Script:
$(document).ready(function() {
var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
var csrfHash = $('.txt_csrfname').val(); // CSRF hash
$('#selectData').select2({
placeholder: '-- Select --',
minimumInputLength: 3,
ajax: {
url: "<?= base_url('servis/getAjax'); ?>",
type: 'POST',
dataType: 'json',
delay: 250,
data: function(params) {
return {
[csrfName]: csrfHash, // CSRF Token
search: params.term
};
},
prosessResults: function(data) {
return {
results: data
};
},
cache: true
},
});
});
Controller:
$search = $this->request->getPost('search');
$result = new MerekModel();
$results = $result->getDataAjax($search);
$selectAjax['token'] = csrf_hash();
$selectAjax = array();
foreach ($results as $row) {
$selectAjax[] = array(
'id' => $row['id_merek'],
'text' => $row['merek'] . ' ' . $row['model'] . ' ' . $row['tipe'],
);
header('Content-Type: application/json');
echo json_encode($selectAjax);
}
Models:
function getDataAjax($search)
{
$data = $this->db->table('tb_merek_tipe')
->select('id_merek, merek, model, tipe')
->orlike('merek', $search)
->orlike('model', $search)
->orlike('tipe', $search)
->get()->getResultArray();
return $data;
}

When I do two operations when select change in javascript error

When I request different data than pressing select, it does not perform a single operation, and when they are combined, only one operation is performed,
It does a process called getStatesByCountryId but it doesn't call get_shipping_price, and because I'm requesting information from two different tables I can't merge them,
And when we merge them, the information is not sent to the span text, so I preferred to separate them,
I using a php codeigniter framework
javascript code:
$("select[name='country']").change(function () {
var countryId = $(this).val();
$.ajax({
url: "/Ajax/getStatesByCountryId",
method: "post",
data: { countryId },
success: function (data) {
var rJson = $.parseJSON(data);
if (rJson.status === true) {
$("select[name='state']").html("");
$.each(rJson.data, function (e, v) {
$("select[name='state']").append(
"<option value='" + v.id + "'>" + v.name + "</option>"
);
});
} else {
$("select[name='state']").html("");
}
}
});
});
$("select[name='country']").change(function () {
var countryname = $(this).val();
$.ajax({
url: "/Ajax/get_shipping_price",
method: "post",
data: { 'countryname': countryname },
success: function (data2) {
if (data2) {
$("span[name='shipping_price']").text(data2.shipping_price);
} else {
$("span[name='shipping_price']").text("");
}
}
});
});
Ajax Code:
public function get_shipping_price()
{
$countryName = $this->request->getPost("countryname");
$result = $this->con->query("SELECT shipping_price FROM table2 WHERE country = '{$countryName}'")->getResult();
if ($result) {
$data2 = array('shipping_price' => $result[0]->shipping_price);
} else {
$data2 = array('shipping_price' => 0);
}
echo json_encode($data2);
}
public function getStatesByCountryId()
{
$countryId = $this->request->getPost("countryId");
$states = $this->con->query("select * from table where ID = {$countryId}")->getResult();
if ($states) {
$data = [
"status" => true,
"data" => $states
];
} else {
$data = [
"status" => false
];
}
echo json_encode($data);
}
and here respon:

pagination automatically sending multiple requests with laravel

hello guys recently I am developing a new website which have multiple filters so I use the session-based filter with laravel
it is working fine if I use only the Show filter one time but when I switch to another filter, it is sending multiple requests(as much time I repeat the filter)
when someone clicks the filter this code will run
<------- Laravel route where I am sending a request it returns me a HTML file and I am rendering in my div tag where I have all lists ------->
public function filter(Request $request){
$course = Course::query();
if (isset($request->show)) {
Session::put('show',$request->show);
$show = $request->show;
}
if(isset($request->type)){
$course->where('type',$request->type);
}
if (isset($request->ratting)) {
$course->where('ratting','>=',$request->ratting);
Session::put('ratting',$request->ratting);
}
if(isset($request->short_type))
{
$type = $request->short_type;
$course = $this->checkSort($course,$type);
Session::put('short',$type);
}
if (Session::has('search')) {
$search = Session::get('search');
$course->where(function($q) use ($search){
$q->where('title', 'LIKE', '%'.$search.'%')
->orWhere('slug', 'LIKE', '%'.$search.'%')
->orWhere('description', 'LIKE', '%'.$search.'%')
->orWhere('keyword', 'LIKE', '%'.$search.'%');
});
}
if(Session::has('show') && !isset($request->show)){
$show = Session::get('show');
}
if(Session::has('ratting') && !isset($request->ratting)){
$course->where('ratting','>=',Session::get('ratting'));
}
if(Session::has('short') && !isset($request->short)){
$type = Session::get('short');
$course = $this->checkSort($course,$type);
}
$course->select('id', 'title', 'slug', 'description', 'created_at', 'regular_price', 'sell_price', 'thumbnail','ratting','status');
return view('site.courses.ajax-listing',[
'active' => 'courses',
'type' => $request->type,
'courses' => $course->where('status',1)->paginate(isset($show) ? $show : 10),
]);
}
public function checkSort($courses,$type){
if($type == "alphabetically_a_z")
{
$courses->orderBy('title', 'ASC');
}
if($type == "alphabetically_z_a")
{
$courses->orderBy('title', 'DESC');
}
if($type == "date_new_to_old")
{
$courses->orderBy('created_at', 'ASC');
}
if($type == "date_old_to_new")
{
$courses->orderBy('created_at', 'DESC');
}
if($type == "popular")
{
$courses->where('is_popular', 1);
}
return $courses;
}
<------------------------------------------->
In the search input have route where i will send request
<input type="text" hidden id="search-url" value="{{route('ajax-search-course')}}">
<--------- Javascript Code ----->
$(document).ready(function(){
var url = "{{route('ajax-search-course')}}";
var Jobtype = "1";
var value;
$("input[name='RattingRadioDefault']:radio").change(function(){
value = $("[name=RattingRadioDefault]:checked").val();
ajaxFilter(url + "?ratting="+value+ "&type=" + Jobtype);
});
$("input[name='ShowingRadioDefault']:radio").change(function(){
value = $("[name=ShowingRadioDefault]:checked").val();
ajaxFilter(url + "?show=" + value + "&type=" + Jobtype);
});
$("input[name='ShortingRadioDefault']:radio").change(function(){
value = $("[name=ShortingRadioDefault]:checked").val();
console.log("this is value",value,$("[name=ShortingRadioDefault]:checked").val());
ajaxFilter(url + "?short_type=" + value + "&type=" + Jobtype);
});
});
function ajaxFilter(url, data = null) {
//Add Preloader
$('#listing-data').hide();
$('#loading-area').show();
$.ajax({
method: 'GET',
url: url,
data: data,
contentType: "application/json; charset=utf-8",
success: function(data) {
// console.log("this is return data",data);
$('#listing-data').html(data);
$('#loading-area').hide();
$('#listing-data').show();
},
error: function(jqXhr, textStatus, errorMessage) {
// error callback
$('#listing-data').hide();
$('#loading-area').show();
console.log("this is error", errorMessage);
}
});
}
<------------- Javascript pagination page ----------->
//Ajax Paginatio
$(document).one('click', '#ajaxPagination ul li a', function (e) {
console.log("ajax pagination function is running",$(this).attr("href"),"and",$(e).attr("href"));
e.preventDefault();
//Add Preloader
$('#listing-data').hide();
$('#loading-area').show();
var url = $(this).attr("href")+"&"+ "type=" + $('#data_sort_filter').attr('job-type'),
data = '';
e.preventDefault();
$.ajax({
method: 'GET',
url: url,
data: data,
contentType: "application/json; charset=utf-8",
success: function (data) {
$('#listing-data').html(data);
$('#loading-area').hide();
$('#listing-data').show();
},
error: function (jqXhr, textStatus, errorMessage) {
// error callback
$('#listing-data').hide();
$('#loading-area').show();
}
});
});
i was trying to add a multiple filters system with the session. now i have this error pagination function running as much i am repeating filters i want to solve this please help me it is a very important to project for me

How to get multiple value from diffrent databases (or models) in codeigniter?

I have 3 table as follow;
Experiments_table
id
method
result loq_value min_clb_value max_clb_value
std_deviation
Items_table
List item
id
experiment_id
related_table
sampling_method
reg_value
Samples_table
sampling_method
related_table,
when i choose sampling_method and related_table in samples_table, I want to automatically create this table;
expirement_id || method || result || std_deviation || reg_value
first, get experiment_ids from items table with samples_table.related_table and sampling_method and fill experiment_id and reg_value in this table.
than, get other parameters (method, result and std_deviation) from experiments_table with experiment_id find in first step from items table.
how to do that in codeigniter 3? please give me a suggestion (view, modal_form, model and controller).
this is my model -> sample_items_model.php
function get_item_suggestion($keyword = "") {
$experiments_table = $this->db->dbprefix('experiments');
$sql = "SELECT $experiments_table.title
FROM $experiments_table
WHERE $experiments_table.deleted=0 AND $experiments_table.title LIKE '%$keyword%'
LIMIT 30
";
return $this->db->query($sql)->result();
}
function get_item_info_suggestion($item_name = "") {
$experiments_table = $this->db->dbprefix('experiments');
$sql = "SELECT $experiments_table.*
FROM $experiments_table
WHERE $experiments_table.deleted=0 AND $experiments_table.title LIKE '%$item_name%'
ORDER BY id DESC LIMIT 1
";
$result = $this->db->query($sql);
if ($result->num_rows()) {
return $result->row();
}
}
this is my controller -> samples.php
/* prepare suggestion of sample item */
function get_sample_item_suggestion() {
$key = $_REQUEST["q"];
$suggestion = array();
$items = $this->Sample_items_model->get_item_suggestion($key);
foreach ($items as $item) {
$suggestion[] = array("id" => $item->title, "text" => $item->title);
}
$suggestion[] = array("id" => "+", "text" => "+ " . lang("create_new_item"));
echo json_encode($suggestion);
}
function get_sample_item_info_suggestion() {
$item = $this->Sample_items_model->get_item_info_suggestion($this->input->post("item_name"));
if ($item) {
echo json_encode(array("success" => true, "item_info" => $item));
} else {
echo json_encode(array("success" => false));
}
}
and this is my modal_form script -> item_modal_form.php
function applySelect2OnItemTitle() {
$("#sample_item_title").select2({
showSearchBox: true,
ajax: {
url: "<?php echo get_uri("samples/get_sample_item_suggestion"); ?>",
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
q: term // search term
};
},
results: function (data, page) {
return {results: data};
}
}
}).change(function (e) {
if (e.val === "+") {
//show simple textbox to input the new item
$("#sample_item_title").select2("destroy").val("").focus();
$("#add_new_item_to_library").val(1); //set the flag to add new item in library
} else if (e.val) {
//get existing item info
$("#add_new_item_to_library").val(""); //reset the flag to add new item in library
$.ajax({
url: "<?php echo get_uri("samples/get_sample_item_info_suggestion"); ?>",
data: {item_name: e.val},
cache: false,
type: 'POST',
dataType: "json",
success: function (response) {
//auto fill the method, unit type and rate fields.
if (response && response.success) {
if (!$("#sample_item_method").val()) {
$("#sample_item_method").val(response.item_info.method);
}
if (!$("#sample_conc_type").val()) {
$("#sample_conc_type").val(response.item_info.conc_type);
}
if (!$("#sample_item_result").val()) {
$("#sample_item_result").val(response.item_info.result);
}
if (!$("#sample_item_loq_value").val()) {
$("#sample_item_loq_value").val(response.item_info.loq_value);
}
if (!$("#sample_item_min_clb_value").val()) {
$("#sample_item_min_clb_value").val(response.item_info.min_clb_value);
}
if (!$("#sample_item_max_clb_value").val()) {
$("#sample_item_max_clb_value").val(response.item_info.max_clb_value);
}
if (!$("#sample_item_std_deviation").val()) {
$("#sample_item_std_deviation").val(response.item_info.std_deviation);
}
}
}
});
}
});
}

how to display more than one result data in select2 using ajax?

i am trying to display some field data from table mysql into the select2 option but whatever i do it still shows me only one.
This is how I expected: Screenshot
Any suggestions? Thanks
in javascript file I have this code
<script type="text/javascript">
//List ajax for list product
$(".js-productList").select2({
ajax: {
url: "halaman/hal_search2ajax/productsList.php",
type: "post",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
};
},
processResults: function(data){
return { results: data };
},
cache: true
},
minimumInputLength: 3,
});
</script>
my code in html
<select name='item' class=\"js-productList form-control\" required></select>
Code in productList.php
<?php
// connect to database
require('../../config/koneksi.php');
$q = $_POST['q'];
$sql = mysql_query("select id_item as id, item_name as text, item_code as code from item where item_name like '%".$q."%'");
$num = mysql_num_rows($sql);
if($num > 0){
while($data = mysql_fetch_assoc($sql)){
//I want to show the item_name and item_code
$tmp[] = $data;
}
} else $tmp = array();
echo json_encode($tmp);
?>
Something like this. Seems to be the typical parse json.
I prefer tu use $.post:
<select name='item' id="itemselect" class=\"js-productList form-control\" required></select>
var data = {
q: params.term // or the way you obtain them
}
$.post('halaman/hal_search2ajax/productsList.php', data, function(response) {
$.each(response,function(i,item){
$('#itemselect').append($('<option>', {
value: item.code,
text : item.code
}));
}
}, 'json');
with append it understand what goes into value and the text
<option value="'+value+'">'+text+'</option>
You just need to manipulate response return by ajax call using map() function
try like this
$(".js-productList").select2({
ajax: {
url: "halaman/hal_search2ajax/productsList.php",
type: "post",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
};
},
processResults: function(data){
output = $.map(data, function (obj) {
obj.text = obj.text + "-" + obj.code
return obj;
});
return { results: output };
},
cache: true
},
minimumInputLength: 3,
});
Here is working example https://jsfiddle.net/6tzkLtvL/2/
I hope it will help you.

Categories