How to append jquery ui autocomplete element? - javascript

I would like to know how to append jquery ui autocomplete elements once the page is active.
The idea is that there are two elements and I would like to add the third element once a submit button is pressed.
Here is my code:
$(function() {
var projects = [{
value: '123',
label: 'Element 1',
desc: 'Element 1 Description',
icon: 'element1icon.png'
},{
value: '456',
label: 'Element 2',
desc: 'Element 2 Description',
icon: 'element2icon.png'
}
,];
$("#desc1").autocomplete({
minLength: 0,
source: projects,
focus: function(event, ui) {
$("#desc1").val(ui.item.label);
return false;
},
select: function(event, ui) {
$("#desc1").val(ui.item.label);
$("#desc-id1").val(ui.item.value);
return false;
}
})
.data('ui-autocomplete')._renderItem = function(ul, item) {
return $('<li>')
.append('<a>' + item.label + '<br>' + item.desc + '</a>')
.appendTo(ul);
};
});
$( "#submit" ).click(function() {
var itemtoadd = $("#addelementtext").val();
alert("This action should insert the element " + itemtoadd);
});
HERE IS THE FIDDLE
EDIT:
The idea is that the old textbox appears with the new element ELEMENT 3 as if it was declared like this:
var projects = [{
value: '123',
label: 'Element 1',
desc: 'Element 1 Description',
icon: 'element1icon.png'
},{
value: '456',
label: 'Element 2',
desc: 'Element 2 Description',
icon: 'element2icon.png'
},{
value: '789',
label: 'Element 3',
desc: 'Elemen 3 Description',
icon: 'element3icon.png'
},
,];

Add it before the button:
$('#submit').before('<input type="text" value="test" />');
http://jsfiddle.net/2GvuB/1/

Related

Dynamic AntD Cascasder. Add and delete options? React Js

I am trying to add an onChange function that can add and delete options in the cascader menu. I would like to be able to select existing menu options and add options on to them as well.
My example data structure looks like this:
const [dataTitle, setDataTitle] = useState([
{
label: '2022',
value: '2022',
children: [
{
label: 'Fall',
value: 'Fall',
children: [
{
label: 'Week 1',
value: 'Week 1',
children: [
{
label: 'Practice 1',
value: 'Practice 1',
},
{
label: 'Practice 2',
value: 'Practice 2',
},
{
label: 'Practice 3',
value: 'Practice 3',
},
{
label: 'Practice 4',
value: 'Practice 4',
},
{
label: 'Game 1',
value: 'Game 1',
},
]
},
{
label: 'Week 2',
value: 'Week 2',
},
{
label: 'Week 3',
value: 'Week 3',
},
],
},
],
},
]);
I am using these onChange events below to add a 'create-new-option' button and to add the new option when prompted.
const handleLabelChange = (value, selectedOptions) => {
const lastOption = selectedOptions[selectedOptions.length - 1];
// Check if the last selected option has a value of 'create-new-option'
if (lastOption.value === 'create-new-option') {
// Prompt user for new option name
const newOptionName = prompt('Enter a name for the new option:');
// Add the new option to the options data
const newOption = {
label: newOptionName,
value: newOptionName,
};
let newDataTitle = [...dataTitle];
let parentOption = newDataTitle.find(o => o.value === lastOption.parentValue);
if (!parentOption) {
parentOption = { children: [] };
newDataTitle.push(parentOption);
}
// Check if parentOption.children is defined before trying to push
if (parentOption.children) {
parentOption.children.push(newOption);
}
setDataTitle(newDataTitle);
}
};
const addCreateNewOption = (options) => {
return options.map(option => {
return {
...option,
children: option.children
? [...addCreateNewOption(option.children), {value: 'create-new-option', label: 'Create new option', parentValue: option.value}]
: [{value: 'create-new-option', label: 'Create new option', parentValue: option.value}]
};
});
};
My issue is having the new option display in the correct spot and under the correct parents. It works correctly with the second level (I can add a 'Spring' Option and it correctly shows up under 2022 / Spring) but none others.
CodeSandbox Recreation

bootbox custom dialog with both radio and select inputs

I'm trying to understand if it's possible to place a select input on the right of a radio input in a custom bootbox dialog. Example:
bootbox.prompt({
title: "This is a prompt with a set of radio inputs!",
message: '<p>Please select an option below:</p>',
inputType: 'radio',
inputOptions: [
{
text: 'Choice One',
value: '1',
},
{
text: 'Choice Two',
value: '2',
},
{
text: 'Choice Three',
value: '3',
}
],
callback: function (result) {
console.log(result);
}
});
This will show three radio items.
I want to place on the right of, say, 'Choice Two' a select:
inputType: 'select',
inputOptions: [
{
text: 'Choose one...',
value: '',
},
{
text: 'Choice One',
value: '1',
}]
But I don't understand if this is possible with bootbox.

TinyMCE: get values from a listbox in a modal window

I'm creating a TinyMCE Plugin for Wordpress. It has a textbox and a listbox field, both staying in a modal window.
Code below:
(function () {
tinymce.create('tinymce.plugins.windowdata', {
init : function(ed, url) {
ed.addButton('showModal', {
title: 'Show Modal',
image: url + '/img/button.png',
onclick: function () {
ed.windowManager.open({
title: 'Minestra',
body: [
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]}, //listbox
],
onsubmit: function () {
var n1 = document.getElementsByClassName('mce-i1n')[0].value; //textbox value
var t1 = document.getElementsByClassName('mce-i1lb')[0].getElementsByTagName('button')[0].getElementsByClassName('mce-txt')[0].innerHTML; //listbox value
ed.execCommand('mceInsertContent', 0, n1+' is of type '+t1) //write contents
}
})
}
});
}
)
My question is about how to get the field values. What i did works very well with the textbox (the n1 var inside the onsubmit() method), but the listbox gets the same text that is shown to TinyMCE user (the text var in each listbox item).
What i want is a way to get the value instead; plus, i suppose i didn't get the right way to do it, not even with textbox. Anyone can help me? Thank you.
Better way to generate content is:
onsubmit: function (e) {
// Insert content when the window form is submitted
e.insertContent('Textbox content: ' + e.data.Field);
e.insertContent('Listbox content: ' + e.data.Listbox)
}
I solved by my own: i had to give a name to all of my fields:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', name: 'Listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]
At this point, to generate my content i got values this way:
onsubmit: function (e) {
e.data.Field;
e.data.Listbox;
}
and used this to write in TinyMCE textarea. To get values back i had to modify textbox field this way:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n', value: ed.selection.getContent()}
Similarly with listbox

.hide() and .show() in jQuery with strange behaivour

I have 3 different blocks of different <section>s.
You can choose second only after <option> in first block.
As well as third, only if <option> from second is chosen.
Changes from first box works ok.
But in second box everything works only for firs two <section>s in third block.
I'm trying to figure out the reason, since functions for both boxes are very similar and my own debugging haven't bring me the victory yet.
http://jsfiddle.net/A1ex5andr/3Lv1f2a8/
$(document).ready(function () {
var sel2 = '#sel2';
var sel3 = '#sel3';
$('#sel1').change(function () {
var selected = $('#sel1 option:selected').attr('id');
var target = "#sel2_";
var sel2New = target + (selected.substr(selected.length-1, 1));
$(sel2New).show();
$(sel2).hide();
sel2 = sel2New;
});
$('.sel2').change(function () {
var selectedMid = $(this).attr('id');
var target_Middle = (selectedMid.substr(selectedMid.length-1, 1));
var selected = $(this).find(":selected").attr('id');
var target = (selected.substr(selected.length-1, 1));
var sel3New = "#sel3_" + target_Middle + '_' + target ;
$(sel3New).show();
$(sel3).hide();
sel3 = sel3New;
});
});
The reason some of your 3rd level lists are not showing up is because of an ID mismatch.
For example, the following declaration is correct:
<select id="sel3_1_2">
The following one is incorrect:
<select id="sel_3_1_3">
Notice the extra underscore between sel and 3. If you do a find a replace in your code for sel_ to sel, I believe everything should start working as you expect.
It is because the IDs on some selects in 3rd block starts with sel_3* and in your javascript you're trying to access sel3*.
You really need to refactor your code!
var myList = [{
value: 'A',
title: 'Value A',
children: [{
value: 'a',
title: 'Small value A',
children: [
{ value: '1', title: 'Value 1' },
{ value: '2', title: 'Value 2' },
{ value: '3', title: 'Value 3' }
]
},{
value: 'b',
title: 'Small value B',
children: [
{ value: '4', title: 'Value 4' },
{ value: '5', title: 'Value 5' },
{ value: '6', title: 'Value 6' }
]
}]
},{
value: 'B',
title: 'Value B',
children: [{
value: 'c',
title: 'Small value C',
children: [
{ value: '7', title: 'Value 7' },
{ value: '8', title: 'Value 8' },
{ value: '9', title: 'Value 9' }
]
},{
value: 'd',
title: 'Small value D',
children: [
{ value: '10', title: 'Value 10' },
{ value: '11', title: 'Value 11' },
{ value: '12', title: 'Value 12' }
]
}]
}];
function createSelect($parent, list) {
var $select = $('<select>');
if ($parent.is('select')) {
$select.insertAfter($parent);
} else {
$select.appendTo($parent);
}
$.each(list, function() {
$('<option>')
.data('children', this.children)
.attr('value', this.value)
.text(this.title || this.value)
.appendTo($select);
});
$select.on('change', function() {
var $self = $(this);
var childList = $self.children('option:selected').data('children');
$self.nextAll().remove();
if (!childList) return;
createSelect($self, childList);
});
$select.trigger('change');
}
function addNone(list) {
list.unshift({ value: '-' });
$.each(list, function() {
if (!this.children) return;
addNone(this.children);
});
}
addNone(myList);
createSelect($('#selectGroup'), myList);
select {
margin: 5px 0;
border-radius: 7px;
background: #5a5772;
color:#fff;
border:none;
outline:none;
cursor:pointer;
width: 203px;
height: 50px;
box-sizing: border-box;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="selectGroup"></div>

How can i use multiselect in Extjs with search as you type

I am using this multiselect feature
http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.form.field.ComboBox-cfg-multiSelect
It works ok and i can select multiple values. But the search as you type only works for the first entry , it don't work for next entry
I want like we selects tags in Stackoverflow question
There is problem with raw ComboBox - it synchronizes selection with value list on picker. To have behaviour as described, you should extend it or find another component.
Below is a example extension, which is not perfect, but may be used as a start point:
Ext.define('Ext.form.field.MultiComboBox', {
extend: 'Ext.form.field.ComboBox',
initComponent: function() {
this.displayTpl = new Ext.XTemplate(
'<tpl for=".">' +
'<tpl if="xindex == xcount">{[typeof values === "string" ? values : values["' + this.displayField + '"]]}</tpl>' +
'</tpl>'
);
this.tpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item x-boundlist-item-no-selection">{' + this.displayField + '}</div>',
'</tpl>'
);
this.multiSelect = true;
this.selection = [];
this.callParent();
},
// when tag is added or removed, this sets size for table cell
adjustSelectedWidth: function() {
var me = this,
cell = me.selectedCell,
width = 0;
cell.select('span.tag').each(function(el) {
width += el.getWidth() + el.getMargin('lr');
});
cell.setWidth(width);
},
// creates table cell for tags, and attaches click handler
afterRender: function(){
var me = this;
me.callParent(arguments);
var triggerWrap = me.triggerWrap,
tr = triggerWrap.down('tr');
// create table cell
me.selectedCell = tr.createChild({
tag: 'td',
cls: Ext.baseCSSPrefix + 'selected-cell'
}, tr.child('td'));
// attach click handler
me.mon(me.selectedCell, {
click: me.onSelectedCellClick,
scope: me
});
me.addChildEls({ name: 'selectedCell', select: '.' + Ext.baseCSSPrefix + 'selected-cell' });
},
// handle click on list
onItemClick: function(picker, record) {
var me = this,
cell = me.selectedCell,
value = record.get(me.valueField),
display = record.get(me.displayField);
if (me.selection.indexOf(record) === -1) {
// TODO: make template
// store selection
me.selection.push(record);
// create element which displays tag
me.selectedCell.createChild({
tag: 'span',
html: display + '<span class="remove-tag"></span>',
cls: 'tag tag-' + value,
recordValue: value
});
}
// adjust width
me.adjustSelectedWidth();
},
onSelectedCellClick: function(event) {
var me = this,
targetEl = event.getTarget('.remove-tag', null),
tagEl = targetEl.parentNode,
match = tagEl && tagEl.className.match(/tag/);
if (match) {
tagEl = Ext.get(tagEl);
var value = tagEl.getAttribute('recordValue');
var index = -1;
// remove value from selection
me.selection = me.selection.filter(function(element, index, array) {
return element.get(me.valueField) != value;
}, me);
// remove element which displays tag
tagEl.remove();
// adjust width
me.adjustSelectedWidth();
}
},
// return value based on selection stored in combo instead of selection model
getValue: function() {
var me = this,
sel = me.selection,
value = '';
for (var i = 0; i < sel.length; ++i) {
value += (i === 0 ? '' : me.delimiter) + sel[i].get(me.valueField);
}
return value;
}
});
Ext.onReady(function() {
Ext.define('Tag', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'}
]
});
var data = {
tags: [
{ name: '00' },{ name: '01' },{ name: '02' },{ name: '03' },{ name: '04' },{ name: '05' },{ name: '06' },{ name: '07' },{ name: '08' },{ name: '09' },
{ name: '10' },{ name: '11' },{ name: '12' },{ name: '13' },{ name: '14' },{ name: '15' },{ name: '16' },{ name: '17' },{ name: '18' },{ name: '19' },
{ name: '20' },{ name: '21' },{ name: '22' },{ name: '23' },{ name: '24' },{ name: '25' },{ name: '26' },{ name: '27' },{ name: '28' },{ name: '29' },
{ name: '30' },{ name: '31' },{ name: '32' },{ name: '33' },{ name: '34' },{ name: '35' },{ name: '36' },{ name: '37' },{ name: '38' },{ name: '39' }
]
};
//note how we set the 'root' in the reader to match the data structure above
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
model: 'Tag',
data : data,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'tags'
}
}
});
Ext.create('Ext.form.Panel', {
renderTo: 'form',
items: [
Ext.create('Ext.form.field.MultiComboBox', {
store: store,
displayField: 'name',
valueField: 'name',
queryMode: 'local',
width: 400
})
]
});
});
Working sample: http://jsfiddle.net/f2JuX/16/

Categories