I use Select 2 in my form where the option data in it I take from the database and I also add an "add new" button when the searched keyword is not in the database. what I want to ask is, what kind of way can I do to be able to create an action from the button. for example when the button is clicked I can display a text field.
For illustration, here is my code:
$('#add_penilai').select2({
placeholder: 'Change Name',
tags : true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(`<button type="button"
class="btn btn-secondary btn-sm ml-10"
onClick='Show()'> + Add New Item</button>`);
}
return $result;
},
escapeMarkup: function (markup) {
return markup;
}
});
.form-control.form-control-hide {
display: none;
}
<select class="form-control select2" id="add_penilai" name="nama_penilai" onchange="isi_otomatis()" data-width="100%">
<option value="Jhony">Jhony</option>
<option value="Kyra">Kyra</option>
<option value="Ronald">Ronald</option>
</select>
<input class="form-control form-control-hide" type="text" id="divisi" name="nama_instansi" />
Related
I create a search box with select2 multi-value select boxes. the data on select2 must list of Title Name that are based on the Project I selected before. But Select2 cannot load the data. Also, there is an error
"Uncaught Error: Option 'ajax' is not allowed for Select2 when attached to a element" how to solve it?
This is Controller Page
function get_title_by_keyword()
{
$keyword = $_POST['keyword'];
$cos_id = implode(',', $_POST['cos_id']);
if (isset($keyword)&&isset($cos_id))
{
die(json_encode($this->menu_model->get_title_by_keyword($keyword,$cos_id)));
}
}
This is Model Page
function get_title_by_keyword($keyword,$cos_id){
$query="SELECT t.id as id , t.name text
FROM db_mstr.m_title t
JOIN db_mstr.m_os os ON t.os_id = os.id
JOIN db_mstr.m_os osC ON os.cos_id = osC.id
JOIN db_mstr.m_bp_title bpt ON t.id = bpt.title_id AND bpt.is_deleted=0
JOIN db_mstr.m_bp bp ON bpt.bp_id = bp.id
where t.id like '%$keyword%' and osC.id in ($cos_id)
GROUP BY t.name";
return $this->db->query($query)->result();
}
This is View Page and JS
<label class="control-label col-sm-1">Project</label>
<div class="col-sm-4">
<select required multiple="multiple" id="title_cos" name="title_cos" class="" style="width:100%" data-placeholder="">
<?php
foreach ($comboCompany as $key)
{
?><option value="'<?=$key->value?>'" > <?=$key->text?> <?php
}
?>
</select>
</div>
<label class="control-label col-sm-1" style="padding-left: 4px;padding-right: 3px;">Title Name</label>
<div class="col-sm-4">
<select required multiple="multiple" class="" id=title_list name="title_list" style="width:100%">
<?php
foreach ($comboTitle as $key)
{
?><option value="<?=$key->id?>" > <?=$key->text?> <?php
}
?>
</select>
</div>
<script>
$(document).ready(function(){
$("#title_list").select2({
ajax: {
url: '<?=base_url();?>index.php/menu/get_title_by_keyword',
dataType: 'json',
type: "POST",
quietMillis: 1000,
data: function (term) {
return {
keyword: term,
cos_id: $('#title_cos').val()
};
},
results: function (data) {
return {
results: data
};
}
},
placeholder: 'Search for Title',
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 3,
});
});
</script>
I am trying to create a multiple choice list using Select2, Razor and the MVC framework. My problem is that the object in the controller that receives the array input is always null. The front-end looks as follows:
<form class="form-horizontal" method="post" action="#Url.Action(MVC.Configurazione.Contatori.Edit())">
<div class="form-group">
<div class="col-lg-8">
<select class="form-control attributoSelect2" name="attributiSelezionati" value="#Model.AttributiSelezionati">
<option value="#Model.AttributiSelezionati" selected>#Model.AttributoDescrizione</option>
</select>
</div>
</div>
</form>
The action method "Edit", is the controller method that receives the array of chosen items from the drop-down list.
The Javascript is the following:
$('.attributoSelect2').select2({
placeholder: "Search attribute",
multiple: true,
allowClear: true,
minimumInputLength: 0,
ajax: {
dataType: 'json',
delay: 150,
url: "#Url.Action(MVC.Configurazione.Attributi.SearchAttrubutes())",
data: function (params) {
return {
search: params.term
};
},
processResults: function (data) {
return {
results: data.map(function (item) {
return {
id: item.Id,
text: item.Description
};
})
};
}
}
});
And finally the C# controller has an object that is expected to retrieve the data from the view and is defined:
public string[] AttributiSelezionati { get; set; }
and the HttpPost method that receives the data is:
[HttpPost]
public virtual ActionResult Edit(EditViewModel model) { }
Could someone give me some insight into what I am doing wrong and the areas that I should change in order to find the problem?
you class name error not attributoSelect2 is attributesSelect2 , I also make this mistake often. haha
<select class="form-control attributoSelect2" name="attributiSelezionati" value="#Model.AttributiSelezionati">
<option value="#Model.AttributiSelezionati" selected>#Model.AttributoDescrizione</option>
</select>
There are multiple reason for not being receiving data on server. First of all you need to change your select code as follow
#Html.DropDownList("attributiSelezionati", Model.AttributiSelezionati, new { #class = "form-control attributo select2" })
now go to console in browser and get the data of element to confirm that your code properly works in HTML & JS
After that you need to add attribute at your controller's action method as
[OverrideAuthorization]
[HttpPost]
You can try the following approach that has been used in some of our projects without any problem:
View:
#Html.DropDownListFor(m => m.StudentId, Enumerable.Empty<SelectListItem>(), "Select")
$(document).ready(function () {
var student = $("#StudentId");
//for Select2 Options: https://select2.github.io/options.html
student.select2({
language: "tr",//don't forget to add language script (select2/js/i18n/tr.js)
minimumInputLength: 0, //for listing all records > set 0
maximumInputLength: 20, //only allow terms up to 20 characters long
multiple: false,
placeholder: "Select",
allowClear: true,
tags: false, //prevent free text entry
width: "100%",
ajax: {
url: '/Grade/StudentLookup',
dataType: 'json',
delay: 250,
data: function (params) {
return {
query: params.term, //search term
page: params.page
};
},
processResults: function (data, page) {
var newData = [];
$.each(data, function (index, item) {
newData.push({
//id part present in data
id: item.Id,
//string to be displayed
text: item.Name + " " + item.Surname
});
});
return { results: newData };
},
cache: true
},
escapeMarkup: function (markup) { return markup; }
});
//You can simply listen to the select2:select event to get the selected item
student.on('select2:select', onSelect)
function onSelect(evt) {
console.log($(this).val());
}
//Event example for close event
student.on('select2:close', onClose)
function onClose(evt) {
console.log('Closed…');
}
});
Controller:
public ActionResult StudentLookup(string query)
{
var students = repository.Students.Select(m => new StudentViewModel
{
Id = m.Id,
Name = m.Name,
Surname = m.Surname
})
//if "query" is null, get all records
.Where(m => string.IsNullOrEmpty(query) || m.Name.StartsWith(query))
.OrderBy(m => m.Name);
return Json(students, JsonRequestBehavior.AllowGet);
}
Hope this helps...
Update:
Dropdown option groups:
<select>
<optgroup label="Group Name">
<option>Nested option</option>
</optgroup>
</select>
For more information have a look at https://select2.org/options.
I am dynamically loading a Select2 input with Ajax. Everything works fine, however, when I try to select a different value, It won't change for some reason. Here's an example of my problem: https://gyazo.com/f9ad7c3ead5fcd1d62740cc44f8d9691
As you can see, the value doesn't change when I click on it. Why does this happen? Maybe it helps when I say that both the first value and the other value have an ID of 1 (its data from different tables in the database) but different texts... How can I make it work?
$('.partnersupplierselect').select2({
ajax: {
dataType: "json",
type: "POST",
data: function (params) {
var group = $(this).parent().parent();
var choice = group.find('.partnersupplier:radio:checked').val();
return {
term: params.term,
'_token': token,
'choice': choice
};
},
url: '{{asset('logs/create/bmi/getpartnerssuppliers')}}',
cache: true,
processResults: function (data) {
return {
results: data
};
}
},
"language": {
"noResults": function () {
return "Geen partners / leveranciers gevonden.";
}
},
escapeMarkup: function (markup) {
return markup;
}
});
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').select2('val', '');
group.find('.partnersupplierselect').select2('data', null);
});
Here's the HTML, but that shouldn't be the problem. But in case someone wants to see it:
<div class="group">
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="partner">
{{Form::radio('partnersupplier', 'partner', true, array('class' => 'mdl-radio__button partnersupplier', 'id' => 'partner'))}}
<span class="mdl-radio__label">Test1 </span>
</label>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect margin-radio" for="supplier">
{{Form::radio('partnersupplier', 'supplier', false, array('class' => 'mdl-radio__button partnersupplier', 'id' => 'supplier'))}}
<span class="mdl-radio__label">Test2 </span>
</label>
<div class="form-group selectdiv" >
<label for="yearlypartnersuppliermaintainance">Blablabla<br></label>
<select id="yearlypartnersuppliermaintainance" name="yearlypartnersuppliermaintainance" class="searchselect searchselectstyle partnersupplierselect">
</select>
</div>
</div>
I figured it out!
I changed:
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').select2('val', '');
group.find('.partnersupplierselect').select2('data', null);
});
to:
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').empty().trigger('change');
});
For some reason, this works and the first thing doesn't. Weird, but at least I got it working!
--- EDIT: Explaining the Flow ---
In the input field, the user is supposed to enter any string which is basically the name of a company they are searching for. Once the user has entered 3 or more characters, an AJAX call goes to the database, and fetches results matching the users query and displays them like search suggestions in Google or your browser URL bar. One the user selects an item from the suggestions, and clicks on the button, a function called setCompany() is triggered which performs different actions.
What I want is that the button which triggers further actions based on the search query, should be disabled UNTIL the user selects an item from the suggestions that Bloodhound, Typeahead has come up with.
--- End EDIT ---
I am using the code below to enable user to select values from the dropdown list that is generated by Typeahead, Bloodhound.
$(document).ready(function() {
//Set up "Bloodhound" Options
var my_Suggestion_class = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "{{ URL::to('user/company/%compquery') }}",
filter: function(x) {
return $.map(x, function(item) {
return {keyword: item['name']};
});
},
wildcard: "%compquery"
}
});
// Initialize Typeahead with Parameters
my_Suggestion_class.initialize();
var typeahead_elem = $('.typeahead');
typeahead_elem.typeahead({
hint: false,
highlight: true,
minLength: 3
},
{
// `ttAdapter` wraps the suggestion engine in an adapter that
// is compatible with the typeahead jQuery plugin
name: 'results',
displayKey: 'keyword',
source: my_Suggestion_class.ttAdapter(),
templates: {
empty: 'No Results'
}
});
});
Here is the HTML:
<div class="iner-sub-header" style="border-bottom: 1px solid #ccc;">
<div class="row" style = "background-color: white;">
<div class="col-md-12 heading">
<div id = "results" class="col-md-12 col-xs-12 results">
<span class="glyphicon glyphicon-search span-search" aria-hidden="true"></span>
<input type="search" class="typeahead custom-input-padding" placeholder="Search Company" id="keyword" onselect="setCompany();">
<button class="btn go-btn" id="go" onclick="setCompany()">SEARCH</button>
</div>
</div>
</div>
</div>
I want to make sure that the button that will trigger setCompany() funtion is disabled until the user selects something from the dropdown that is generated by Typeahead.
Can anyone please help me out?
Try
html
<button class="btn go-btn" id="go" onclick="setCompany()" disabled="true">SEARCH</button>
js
typeahead_elem.bind("typeahead:select", function(ev, suggestion) {
$("#go").prop("disabled", false);
});
See disabled , typeahead.js - Custom Events
This made it work for me. Now its working perfectly.
$(document).ready(function() {
//Set up "Bloodhound" Options
var my_Suggestion_class = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "{{ URL::to('user/company/%compquery') }}",
filter: function(x) {
return $.map(x, function(item) {
return {keyword: item['name']};
});
},
wildcard: "%compquery"
}
});
// Initialize Typeahead with Parameters
my_Suggestion_class.initialize();
var typeahead_elem = $('.typeahead');
typeahead_elem.typeahead({
hint: false,
highlight: true,
minLength: 3
},
{
// `ttAdapter` wraps the suggestion engine in an adapter that
// is compatible with the typeahead jQuery plugin
name: 'results',
displayKey: 'keyword',
source: my_Suggestion_class.ttAdapter(),
templates: {
empty: 'No Results'
}
}).on("typeahead:selected typeahead:autocompleted", function(ev, my_Suggestion_class) {
$("#go").prop("disabled", false);
});
});
I wanted a way to re-disable the button if the button if the textbox's content changes and isn't a typeahead selected value. On typeahead:select I store the display text. On every key up I ensure the text still matches the stored variable. Otherwise I disable the button again.
this.searchbox = $('.js-patient-search');
this.searchbox.typeahead({
hint: true
}, {
source: Bloodhound,
display: function(obj) {
return obj.first_name + ' ' + obj.last_name;
}
});
this.searchbox.on('typeahead:select', (function(_this) {
return function(e, suggestion) {
_this.displayName = _this.searchbox.val();
return $('.js-add-encounter').prop('disabled', false);
};
})(this));
return this.searchbox.keyup((function(_this) {
return function(e) {
if (_this.searchbox.val() !== _this.displayName) {
return $('.js-add-encounter').prop('disabled', true);
}
};
})(this));
NOTE: This is parsed coffeescript but I think it should be fairly clear what's going on.
I have a select2 (jQuery plugin) on my code which works normally except for the case when I select an item.
The value is wrong.
Form:
<form id="Teste" method="get" action="">
<input type="hidden" id="e6" name="e6" class="select2" style="width: 600px;" />
<input type="submit" value="Send" />
</form>
Input from select2 - hidden (required for remote data) - value: [Object]:
<input type="hidden" id="e6" name="e6" class="select2 select2-offscreen" style="width: 600px;" tabindex="-1" title="" value="[object Object]">
Javascript used for instance select2:
function formatRes(item) {
return item.Text;
}
function formatSel(item) {
return item.Value;
}
$("#e6").select2({
placeholder: "Select your supplier",
minimumInputLength: 0,
id: function(data){return {id: data.id};},
allowClear: true,
ajax: {
url: "http://localhost:1396/List/_GetDropDownListSupplier",
dataType: 'jsonp',
quietMillis: 300,
data: function (term, page) {
return {
searchString: term,
pageSize: 60,
pageIndex: page,
};
},
results: function (data, page) {
return {results: data.results, more: (page * 60) < data.total };
}
},
formatResult: formatRes,
formatSelection: formatSel,
dropdownCssClass: "bigdrop",
escapeMarkup: function (m) { return m; }
});
Json example returned by ajax to Select2:
{"results":[{"Selected":false,"Text":"Cezar Barbara","Value":"724"},{"Selected":false,"Text":"Cezar Barbara","Value":"765"}],"total":82}
Solved:
id: function(data){return data.Value;}
I was returning a object with id and not a directly value.
Thanks to #mgibsonbr from Stackoverflow PT
You need to use a select element, try this:
<form>
...
<select id="someSelect">
//options
</select>
<input type="hidden" name="fromSelect" id="fromSelect" value=""/>
</form>
You have two options here:
1.- Get the value direct from select:
var selected = $('#someSelect').val();
2.- Assign the value to the hidden input and then get its value:
$('#someSelect').on('change', function(){
$('#fromSelect').attr('value', this.value);
});
var selected = $('#fromSelect').val();