Stop .blur() function from triggering on select statement but remain on span - javascript

I am trying to create an inline edit function to trigger differently on different elements.
I have tried to use other plugins but haven't been able to get them to do exactly what I want so have decided to try to create a plugin of my own, while learning jquery along the way.
The issue I am currently having is that I have a .blur event that is triggering on a span element correctly and this is what I want but when the element is a select element I don't want the blur event to trigger. As the code is below the blur event triggers and it is not the desired result. Can anybody advise how I can only trigger the blur() event on span elements and nothing else
$('.inlineEdit-jmc').inlineEditJmc({
fieldsArray: {
table-column1: 'field-table-column1',
table-column2: 'field-table-column2'
}
});
(function ( $ ) {
$.fn.inlineEditJmc = function(options) {
//Set Default Settings
console.log(options);
var settings = $.extend({
'pk': null,
'table': null,
'field': null,
'url': null,
'type': null,
'fieldsArray': null
},options)
if(settings.fieldsArray == null){}else{
var fields = new Array();
}
function load_settings(this_selected){
settings['pk'] = this_selected.attr("data-pk"); // pk of table to be updated
settings['table'] = this_selected.attr("data-table"); // table name of table to be updated
settings['field'] = this_selected.attr("data-field"); // name of the field in the table being updated
settings['url'] = this_selected.attr("data-url"); // url for the ajax call to be sent to.
settings['type'] = this_selected.attr("data-type"); // type of input being used. Input or Select
settings['value'] = this_selected.text(); //
settings['class'] = this_selected.attr("class"); // The Class
console.log(settings['table'] +' '+ settings['value']+ ' '+ settings['class']);
// if there are optionional inserts passed lets grab them
console.log('passed options:');
if(settings.fieldsArray == null){}else{
//var fields = [];
$.each(settings.fieldsArray,function(k,v){
//console.log('settings['+k+'] '+this_selected.attr(v));
$obj={};
$obj[k] = this_selected.attr(v);
fields.push($obj);
});
}
}
$(this).on('mouseover', function(event) {
$(this).addClass("ui-state-hover");
}).on('mouseout', function(event) {
$(this).removeClass("ui-state-hover");;
});
if($(this).is('select')){
$(this).on('change', function(){
alert('changed');
alert($(this).val());
//console.log($(this));
//load_settings($(this));
var nt = $(this).text();
var jsonstring = JSON.stringify(fields);
// AJAX
});
}
if($(this).is('span')){
$(this).on("blur", function () {
alert('span');
load_settings($(this));
var nt = settings['value']
console.log('comment: '+settings['value']);
// we are going to update the db here.
console.log('Insert');
console.log(fields);
var jsonstring = JSON.stringify(fields);
console.log(jsonstring);
$.ajax({
type: 'POST',
url: settings['url'],
data: {
fieldsArray: fields,
pk: settings['pk'],
table: settings['table'],
field: settings['field'],
value: settings['value']
},
cache: false,
success: function(data,status){
console.log(data);
}
});
});
}
}
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<td class=''>
<select class='inlineEdit-jmc' ><option value='0' data-pk='3' data-url='/path/to/js/ajax/ajax.php' data-table='mysqltablename' data-field='ignore'>NO</option>
<option value='1' data-pk='3' data-url='/path/to/js/ajax/ajax.php' data-table='mysqltablename' data-field='ignore' selected>YES</option>
</select></td>
<td class=''><span class='inlineEdit-jmc' id='input' data-pk='3' data-url='/path/to/js/ajax/ajax.php' data-table='mysqltablename' data-field='comment' contenteditable='true'>Text that can be edited</td>

Try this code section in place of yours that begins if($(this).is('span')){
$(this).on("blur", function ()
$("span").on("blur", function () {
// your function content here
});
$("span select").on("blur", function () {
e.stopPropagation();
});
The two alternative selectors act like a case statement in jQuery

Related

Dynamically populate a form field based on a previous user entry

I have an application that is using Flask and wtforms and part of the functionality is to take user input for the first two fields and populate the remainder of the form fields which are of type SelectMultipleField (I'm going to refer to these as select fields) with choices from a database based on the first two fields (I'm going to refer to these as entry fields).
My issue right now is getting the select fields to dynamically populate. I found a solution here and this seems to be exactly what I need. It instantiates the select fields to all possible choices and then when it detects a JQuery "onchange" event in the entry fields, filters the select fields to choices based on the user entry for the entry fields. An example would be a user entering a specific company into the form and the select fields populating with "locations" only for that company.
However, in adapting this solution to my problem, I have not been able to get the code to run and I have researched far and wide and unable to resolve this. I'm new to both JQuery and Stack Overflow so any help would be greatly appreciated. Below is my code. Note that I am only focusing on one of the entry fields and dynamically populating just one of the select fields until I get this to work. Test_table is the entry field and test_join_key is the select field.
Here's the form with relevant fields-
class QaForm(FlaskForm):
test_table_in = StringField('Test Table', validators=[DataRequired()], id= 'test_table')
test_join_key = SelectMultipleField("Select Test Fields to Join on", choices=[], coerce=str, id = 'select_test_join_key')
Flask view to instantiate all the select fields -
#app.route('/', methods = ['GET', 'POST'])
#app.route('/home', methods = ['GET', 'POST'])
def home():
form = QaForm()
fields_query = f"""select column_name AS Fields from information_schema.columns group by 1;"""
conn.execute(fields_query)
result = conn.fetchall()
select_choices = [(column, column) for column in result]
form.test_join_key.choices = select_choices
Flask view to get choices for select fields based on user input for entry field -
#app.route('/_get_fields/<table>')
def _get_fields(table):
table = request.args.get(table, type=str)
fields_query = f"""select column_name AS Fields from information_schema.columns WHERE table_name = '{table}' group by 1;"""
conn.execute(fields_query)
result = conn.fetchall()
select_choices = [(column, column) for column in result]
return jsonify(select_choices)
JQuery to detect input in entry field and filter choices for select field (injected in HTML file)-
<script charset="utf-8" type="text/javascript">
$function() {
var dropdown = {
test_table: $('#test_table')
test_join_key: $('#select_test_join_key')
}
updateFields();
function updateFields() {
var send = {
test_table: dropdown.test_table.val()
};
dropdown.test_join_key.attr('disabled', 'disabled');
dropdown.test_join_key.empty();
$.getJSON("{{url_for('_get_fields') }}", send, function(data) {
data.forEach(function(item) {
dropdown.test_join_key.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.test_join_key.removeAttr('disabled');
});
}
dropdown.test_table.on('change', function() {
updateFields();
});
});
</script>
EDIT: Using #Ibsn suggestions, I was able to get the JQuery snippet to run for one form field. However, updating it to perform the same actions for multiple fields using parameters for the function again results in the code not running. I've checked to make sure my syntax is correct based on the tutorial on W3 schools as well as other Stack Overflow questions but still unable to get it to run. Here's the updated Jquery to detect input in entry fields and filter choices for select fields -
<script charset="utf-8" type="text/javascript">
$(function() {
var tables = {
test_table: $('#test_table'),
prod_table: $('#prod_table')
};
var fields = {
test_join_key: $('#select_test_join_key'),
prod_join_key: $('#select_prod_join_key'),
test_dimensions: $('#select_test_dimensions'),
prod_dimensions: $('#select_prod_dimensions'),
test_measures: $('#select_test_measures'),
prod_measures: $('#select_prod_measures')
};
updateFields(table, field);
function updateFields(table, field) {
var send = {
table: tables.table.val()
};
fields.field.attr('disabled', 'disabled');
fields.field.empty();
$.getJSON("{{url_for('_get_fields') }}", send, function(data) {
data.forEach(function(item) {
fields.field.append(
$('<option>', {
value: item[1],
text: item[0]
})
);
});
fields.field.removeAttr('disabled');
});
}
tables.test_table.on('change', function() {
updateFields(tables.test_table, fields.test_join_key);
updateFields(tables.test_table, fields.test_dimensions);
updateFields(tables.test_table, fields.test_measures);
});
tables.prod_table.on('change', function() {
updateFields(tables.prod_table, fields.prod_join_key);
updateFields(tables.prod_table, fields.prod_dimensions);
updateFields(tables.prod_table, fields.prod_measures);
});
});
There are a couple of syntax errors in your code.
$function() {} should be $(function(){}). And you're missing the comma between properties on var dropdown = {}
This is the updated version:
<script charset="utf-8" type="text/javascript">
$(function(){
var dropdown = {
test_table: $('#test_table'),
test_join_key: $('#select_test_join_key')
}
updateFields();
function updateFields() {
var send = {
test_table: dropdown.test_table.val()
};
dropdown.test_join_key.attr('disabled', 'disabled');
dropdown.test_join_key.empty();
$.getJSON("{{url_for('_get_fields') }}", send, function(data) {
data.forEach(function(item) {
dropdown.test_join_key.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
dropdown.test_join_key.removeAttr('disabled');
});
}
dropdown.test_table.on('change', function() {
updateFields();
});
});
The OP updated the question with new requirements
If I understand correctly, you're trying to update all the test_ fields when test_table changes and all the prod_ fields when prod_table changes.
So this code should do that:
$(function () {
var tables = {
test_table: $('#test_table'),
prod_table: $('#prod_table')
};
// I'm organizing fields in two arrays, test and prod, for simplyfing iterate over each group
var fields = {
test: [$('#select_test_join_key'), $('#select_test_dimensions'), $('#select_test_measures')],
prod: [$('#select_prod_join_key'), $('#select_prod_dimensions'), $('#select_prod_measures')]
};
// This is for updating fields the first time
fields.test.forEach(item => updateFields(tables.test_table, item));
fields.prod.forEach(item => updateFields(tables.prod_table, item));
function updateFields(table, field) {
var send = {
table: table.val()
};
field.attr('disabled', 'disabled');
field.empty();
$.getJSON("{{url_for('_get_fields') }}", send, function (data) {
data.forEach(function (item) {
field.append(
$('<option>', {
value: item[0],
text: item[1]
})
);
});
field.removeAttr('disabled');
});
}
// Test fields and prod fields are two arrays now, so I can simply iterate through them
tables.test_table.on('change', function () {
fields.test.forEach(item => updateFields(tables.test_table, item));
});
tables.prod_table.on('change', function () {
fields.prod.forEach(item => updateFields(tables.prod_table, item));
});
});

Kendo textbox within dropdownlist

is possible to make textbox within the dropdownlist from Kendo? When user won't find on list what he needs, there should be textbox to set manually some value.
dropdown:
#(Html.Kendo().DropDownList()
.Name("Id")
.DataTextField("StringValue")
.DataValueField("Id")
.SelectedIndex(0))
javascript:
$('#AttributeValue_Id').kendoDropDownList({
dataSource: dataSource,
dataTextField: "Text",
dataValueField: "Value",
optionLabel: '#Html.Raw(T("Product.Attribute.SelectValue"))',
dataBound: function () {
$('#AttributeValue_Id').data('kendoDropDownList').select(0);
}
});
Values in this dropdown depend on another dropdown, where we pick attribute and then this dropdown is getting new data dynamically. Somebody know any solution?
Ok I solved this issue. Solution is:
when the element on dropdown filter is not exist, I can write my string value and redirect to AddNew function. Javascript for no data template:
<script id="noDataTemplate" type="text/x-kendo-tmpl">
<div>
Didn't find the element
</div>
<br />
<button class="k-button" onclick="addNew('#: instance.element[0].id #', '#: instance.filterInput.val() #')">Add new value</button>
AddNew function is get widget element and my value. If user will confirm the script will redirect to action from controller sending needed values - productId from Model, value from parameter and attributeDefinitionId value from first dropdown:
function addNew(widgetId, value) {
var widget = $("#" + widgetId).getKendoDropDownList();
var attributeDefinition = $('#AttributeDefinition').data('kendoDropDownList').value();
var dataSource = widget.dataSource;
if (confirm("Are you sure?")) {
$.ajax({
url: '#Url.Action("AddAttributeValue", "Product")' + '?productId=#Model.Id' + '&value=' + value + '&attributeDefinition=' + attributeDefinition,
cache: false,
}).done(function () {
var grid = $("#attributesGrid").data("kendoGrid");
grid.dataSource.read();
});
dataSource.one("sync", function () {
widget.select(dataSource.view().length - 1);
});
dataSource.sync();
}
};
In controller I'm getting these values and insert them to database:
public ActionResult AddAttributeValue(int productId, string value, int attributeDefinition)
{
if (value != null)
{
try
{
var model = attributeValueRepository.Insert(new ProductAttributeValue()
{
IsCustom = true,
StringValue = value,
AttributeDefinitionId = attributeDefinition,
});
productAttributeRepository.Insert(new ProductAttribute()
{
AttributeValueId = model.Id,
ProductId = productId
});
} catch
{
AddErrorFlashMessage(T("Product.Attribute.AttributeValueError"));
return BadRequest();
}
}
return Ok();
}
Edit
Almost forgot, I set also on dropDown noDataTemplate:
$('#AttributeValue_Id').kendoDropDownList({
dataSource: dataSource,
dataTextField: "Text",
dataValueField: "Value",
optionLabel: '#Html.Raw(T("Product.Attribute.SelectValue"))',
filter: "startswith",
noDataTemplate: $("#noDataTemplate").html(),
dataBound: function () {
$('#AttributeValue_Id').data('kendoDropDownList').select(0);
}
});
Thanks everybody for the tips
Might be late for an answer but kendo dropdownlist supports contains filter for exactly this workflow.
<%= Html.Kendo().DropDownList()
.Name("DropDownList")
.Filter(FilterType.Contains);
%>
Ref: Kendo UI Dropdownlist API
Kendo already have feature within Dropdownlist in case user unable to find his choice option. He can add new element manually in dropdownlist. Please find link below
https://demos.telerik.com/kendo-ui/dropdownlist/addnewitem

How can I kill all my functions after execution?

I have a condition column == 1 and if this is the case, the function MakeCellsEditable and the function myCallbackFunction are initialized:
<script src="https://raw.githubusercontent.com/ejbeaty/CellEdit/master/js/dataTables.cellEdit.js"></script>
$(document).ready(function () {
var table = $('#myTable').DataTable();
$('#myTable tbody').on('mousedown', 'td', function () {
$('#myTable').data('column', table.cell(this).index().columnVisible);
});
if (column == 1) {
table.MakeCellsEditable({
"onUpdate": myCallbackFunction
});
}
});
function myCallbackFunction(updatedCell, updatedRow, oldValue) {
var array = updatedRow.data();
var id = array[0];
var column = $('#myTable').data('column');
console.log("The column is: " + column);
jQuery.ajax({
type: "POST",
url: "update.php",
data: {
updatedCell: updatedCell.data(),
id: id,
column: column,
},
cache: false
});
}
What I want to do is, after the functions are executed, I want to kill them. Because otherwise if I one time clicked column 1, then all my tables are editable (not only column 1).
I tried table.unbind(); or table.die(), but this didn't work out.
I tested at the end of the code:
function destroyTable() {
if ($.fn.DataTable.isDataTable('#myTable')) {
table.destroy();
table.MakeCellsEditable("destroy");
}
}
But it didn't work out
To answer the question in the headline: Yep:
function thiswilljustworkonce(){
alert("once");
this.thiswilljustworkonce=function(){};
}
thiswilljustworkonce();
thiswilljustworkonce();
Use columns option for CellEdit plugin to specify which column needs to be editable. There would be no need to remove event handler.
var table = $('#example').DataTable();
function myCallbackFunction (updatedCell, updatedRow, oldValue) {
console.log("The new value for the cell is: " + updatedCell.data());
console.log("The values for each cell in that row are: " + updatedRow.data());
}
table.MakeCellsEditable({
"columns": [0],
"onUpdate": myCallbackFunction,
"confirmationButton": true
});
See this example for code and demonstration.

Passing Kendo Grid selected item into Kendo Window

I have got a Kendo Grid with editable records:
When the user clicks the edit button, a Kendo Window opens with a form to edit the record.
I am achieving this by filling the Kendo Window from a controller method that fetches the data of the selected record via webservice: <- this is what I want to avoid. Instead, I want to take the data straight out from the table and put it into the input fields inside the Kendo Window, without any additional processing or html calls. The data is already on the table, I just don't know how to send it to the Kendo Window inputs.
Here's some code:
The javascript function called after clicking the edit button:
function openEdit() {
var window = $("#editWindow").getKendoWindow();
window.refresh({
url: '#Url.Action("_EditForm", "Controller")'
});
window.center().open();
}
The view contains a partial view call:
#Html.Partial("_EditWindow")
The called partial view contains the Kendo Window:
#(Html.Kendo().Window()
.Name("editWindow")
.Modal(true)
.Events(e => e.Open("drawWindow").Close("refresh").Refresh("hideLoading"))
.Iframe(true)
.Visible(false)
.Title("Edit Record")
)
How can the data from the selected row of the table be passed to the Kendo Window?
EDIT
I know how to get the values from the selected record in javascript:
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
I just don't know how to pass them into the Kendo Window inputs.
I came to a solution for my problem. I now send the selected model from the view to the controller. I use the fantastic JSON.stringify to achieve it.
function onChange() {
if (this.dataItem(this.select()) != null) {
var rowModel = this.dataItem(this.select());
// gets the model of the selected item in the grid
$.ajax({
url: 'sendGridRecord',
type: "POST",
data: JSON.stringify(rowModel),
contentType: 'application/json'
});
}
}
You can define a partial view as per the requirement and render that on a kendow window on edit button click.i.e
#(Html.Kendo().Window().Name("myWindow")
.Content(Html.Partial(#Url.Content("~/Views/_EditWindow.cshtml")).ToString())
.Visible(false).Title("XYZ").Modal(true).Actions(actions => actions
.Custom("custom")
.Minimize()
.Maximize()
.Close()
).Resizable().Draggable())
function openEdit() {
//Open the kendow window here.
//Get the seleceted item
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
//populate the partial view fields using the selectedItem variable like
$('#name').val(selectedItem.Name);
}
You can use these two methods in order to pass the Kendo().Grid()'s selected row data:
Method I:
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
#(Html.Kendo().Button()
.Name("myBtn")
.HtmlAttributes(new { type = "button", #class = "k-primary k-button k-button-icontext", onclick = "callActionBySelectedRowId('#GridMaster')" })
.Content("Add New")
)
</div>
</text>);
})
function callActionBySelectedRowId(grid) {
var grid = $(grid).data('kendoGrid');
id = grid.dataItem(grid.select()).ID;
window.location.href = '#Url.Action("YourAction", "YourController")/' + id;
}
Method II:
View:
#(Html.Kendo().Grid<KendoMVCWrappers.Models.Person>().Name("persons")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(m => m.PersonID);
})
.Read(read => read.Action("GetPersons", "Home"))
.Update(up => up.Action("UpdatePerson", "Home"))
)
.Selectable(s => s.Mode(GridSelectionMode.Multiple))
.Columns(columns =>
{
columns.Bound(c => c.BirthDate);
columns.Bound(c => c.Name);
columns.Command(cmd => cmd.Edit());
})
.Pageable()
.Sortable()
)
<input type="button" id="btn" name="name" value="send to Server!" />
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
var items = {};
var grid = $('#persons').data('kendoGrid');
var selectedElements = grid.select();
for (var j = 0; j < selectedElements.length; j++) {
var item = grid.dataItem(selectedElements[j]);
items['persons[' + j + '].Name'] = item.Name;
items['persons[' + j + '].PersonID'] = item.PersonID;
}
//If you want to pass single item parameter use this and comment out "for loop" & use the second "data" line below:
//var singleItem = grid.dataItem(selectedElements[0]);
$.ajax({
type: "POST",
data: items,
//data: { ID: singleItem.ID }, //for passing single item parameter
url: '#Url.Action("Test","Home")',
success: function (result) {
console.log(result);
}
})
})
})
Controller:
public ActionResult Test(Person[] persons)
{
return Json(persons);
}
Note: If the View called from Controller cannot be rendered use the javascript function as below by using window.location.href instead of $.ajax
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
var items = {};
var grid = $('#persons').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
window.location.href = '#Url.Action("YourAction", "YourController")/' + item.ID;
})
})
</script>

Bootstrap Multiselect update option list on flow

I use bootstrap multi-select and I want to update options on flow with ajax
To populate on init my multiselect I do
<select name="model" class="multiselect" multiple="multiple">
<? foreach ($sel_models as $mod) { ?>
<option value="<?= $mod ?>" <?= ($mod == $params['model']) ? 'selected' : '' ?>><?= $mod ?></option>
<? } ?>
</select>
then on event I would like to update my option list with the following ajax
I was trying to use the rebuild method but won't fire the drop-down after creation
$.ajax({
type: 'post',
url: "helper/ajax_search.php",
data: {models: decodeURIComponent(brands)},
dataType: 'json',
success: function(data) {
$('select.multiselect').empty();
$('select.multiselect').append(
$('<option></option>')
.text('alle')
.val('alle')
);
$.each(data, function(index, html) {
$('select.multiselect').append(
$('<option></option>')
.text(html.name)
.val(html.name)
);
});
$('.multiselect').multiselect('rebuild')
},
error: function(error) {
console.log("Error:");
console.log(error);
}
});
With firebug I can see that the list is generated but on select won't show up
In the doc I can read :
.multiselect('setOptions', options)
Used to change configuration after initializing the multiselect. This may be useful in combination with .multiselect('rebuild').
Maybe you can't change your widget data by your initial way. In a correct way you should use setOptions method.
Else : With your way, maybe should you think about destroy your widget .multiselect('destroy') and create it again after.
Update after comment :
In the doc : ( you've linked )
Provides data for building the select's options the following way:
var data = [
{label: "ACNP", value: "ACNP"},
{label: "test", value: "test"}
];
$("#multiselect").multiselect('dataprovider', data);
So :
When you get data from your ajax call, you have to create an array of objects ( it's the options in the select you want to have ) with the format like
var data =
[
{label: 'option1Label', value: 'option1Value'},
{label: 'option2Label', value: 'option2Value'},
...
]
When your objects array is created, then you just have to call the method
$("#multiselect").multiselect('dataprovider', data);
Where data is your array of objects.
I hope I'm clear :/
As an alternative to multiselect('dataprovider', data) you can build the list with jquery append exactly the way you did in your question. The only change you need to make is to delay the rebuild until after the ajax request is complete.
var buildDrivers = $.getJSON('resources/orders/drivers.json', function(data) {
$.each(data, function(i, driver) {
$('#toolbar select[name="drivers"]').append('<option>'+driver+'</option>');
});
});
buildDrivers.complete(function() {
$('.multiselect').multiselect('rebuild');
});
see http://api.jquery.com/jquery.getjson/ for documentation
I've been added the functionality of updating options after filtering and getting them from the server side. This solution relays on the concept of injecting new options, destroying the select and initializing it again.
I took into account:
Considering the existing selected options, which must stay.
Removing duplicate options (might be as a conflict from which that already selected and the new that came from the server).
Keeping the options tray open after the update.
Reassign the previous text in the search text box & focusing it.
Just add the 'updateOptions' as a function after the 'refresh' function along with the two helper functions as follows:
updateOptions: function (options) {
var select = this.$select;
options += this.getSelectedOptionsString();
var selectedIds = select.val(),
btnGroup = select.next('.btn-group'),
searchInput = btnGroup.find('.multiselect-search'),
inputVal = searchInput.val();
options = this.removeOptionsDuplications(options);
if (!options) {
options = '<option disabled></option>';
}
// 1) Replacing the options with new & already selected options
select.html(options);
// 2) Destroyng the select
select.multiselect('destroy');
// 3) Reselecting the previously selected values
if (selectedIds) {
select.val(selectedIds);
}
// 4) Initialize the select again after destroying it
select.multiselect(this.options);
btnGroup = select.next('.btn-group');
searchInput = btnGroup.find('.multiselect-search');
// 5) Keep the tray options open
btnGroup.addClass('open');
// 6) Setting the search input again & focusing it
searchInput.val(inputVal);
searchInput.focus();
},
getSelectedOptionsString: function () { // Helper
var result = '',
select = this.$select,
options = select.find('option:selected');
if (options && options.length) {
$.each(options, function (index, value) {
if (value) {
result += value.outerHTML;
}
});
}
return result;
},
removeOptionsDuplications: function (options) { // Helper
var result = '',
ids = new Object();
if (options && options.length) {
options = $(options);
$.each(options, function (index, value) {
var option = $(value),
optionId = option.attr('value');
if (optionId) {
if (!ids[optionId]) {
result += option[0].outerHTML;
ids[optionId] = true;
}
}
});
}
return result;
},
Demo:
State:
"Option 1"
$('#select').multiselect('updateOptions', '<option value="2">Option 2</option>');
State:
"Option 2"
"Option 1"
I think this is an easier way to add options on the fly (using ajax or any other listener) to an existing Bootstrap MultiSelect.
Following is a simplified example to add options:
function addOptionToMultiSelect(multiselectSelector, value, selected) {
var data = [];
$(multiselectSelector + ' option').each(function(){
var value = $(this)[0].value;
var selected = $(this)[0].selected;
data.push({label: value, value: value, selected: selected});
});
// Add the new item
data.push({label: value, value: value, selected: selected});
$(multiselectSelector).multiselect('dataprovider', data);
}
For simplicity, I have assumed both the label and value are the same in an option. Note that the already selected options are taken care of by reading the selected attribute from the existing options. You can make it more sophisticated by tracking the disabled and other attributes.
Sample:
addOptionToMultiSelect('#multiselect-example', 'new-option', true);

Categories