Dropmenu

Dropmenu open at cursor position

click here
Open a dropmenu upon clicking a div, positioning the menu dynamically based on the cursor's X and Y coordinates.
Dropmenu/Index.cshtml
<div id="area1" class="area">
<div class="msg">click here</div>
</div>
<script>
$(function () {
const div = $('#area1');
const msg = div.find('.msg');

div.on('click', (e) => {
awe.dropmenu({
dataFunc: () => [{ k: 1, c: 'item 1' }, { k: 2, c: 'item 2' }, { k: 3, c: 'item 3' }],
select: (item) => msg.html('you clicked ' + item.c),
autoOpen: { xy: { y: e.clientY, x: e.clientX } }
});
});
});
</script>

Dropmenu set opener

Open a dropmenu with an opener defined, which will make the dropmenu position itself based on the position of that opener.
Dropmenu/Index.cshtml
<button type="button" class="awe-btn" onclick="openDropMenu1(this)">click to open menu</button>
<button type="button" class="awe-btn awe-btnp" onclick="openDropMenu1(this)">same dropmenu</button>
<script>
function openDropMenu1(opener){
awe.dropmenu({
dataFunc: () => [...Array(10).keys()].map(x => ({ k: x, c: `item ${x}` })),
select: (item) => $(opener).html(item.c).focus(),
autoOpen: { opener }
});
}
</script>

Dropmenu with different items depending on what is clicked

a
b
c
click here, or on a card
Shared/Demos/DropmenuItems.cshtml
<div class="area" id="area2">
<div class="card">
<div class="big">a</div>
</div>
<div class="card">
<div class="big">b</div>
</div>
<div class="card">
<div class="big">c</div>
</div>
<div class="msg">click here, or on a card</div>
</div>
<script>
$(function() {
var div = $('#area2');

var msg = div.find('.msg');

div.on('click', function(e) {
var card = $(e.target).closest('.card');

awe.dropmenu({
dataFunc: (getData) => {
const items = [{ k: 1, c: 'item 1' }, { k: 2, c: 'item 2' }];

if (card.length) {
items.push({ k: 'hide', c: 'hide card ' + card.find('.big').html(), i: card.index() });
}

if (div.find('.card:hidden').length) {
items.push({ k: 'all', c: 'show all' });
}

return items;
},
select: select,
autoOpen: { xy: { y: e.clientY, x: e.clientX } }
});
});

function select(it) {
msg.html('you clicked ' + it.c);
if (it.k == 'hide') {
div.find('.card').eq(it.i).hide();
} else if (it.k == 'all') {
div.find('.card').show();
}
}
});
</script>

Mainmenu and sidemenu

open on click:




open on hover:




side menu, open on hover:

File
Meals
Help
Dropmenu/Index.cshtml
<p>open on click:</p>
<div id='menu1'>
<div class="mitem" data-prop="file">File</div>
<div class="mitem" data-prop="meals">Meals</div>
<div class="mitem" data-prop="help">Help</div>
</div>
<br />
<br />
<br />

<p>open on hover:</p>
<div id='menuHov1'>
<div class="mitem" data-prop="file">File</div>
<div class="mitem" data-prop="meals">Meals</div>
<div class="mitem" data-prop="help">Help</div>
</div>

<br />
<br />
<br />
<p>side menu, open on hover:</p>
<div id='sideMenu' style="width: 100px">
<div class="smitem" data-prop="file">File</div>
<div class="smitem" data-prop="meals">Meals</div>
<div class="smitem" data-prop="help">Help</div>
</div>
<div id="log1" style="min-height: 2em;"></div>
<script>
$(function () {
var data = {
file: [
{ c: 'New' },
{ c: 'Save' },
{
c: 'Recent Files',
nv: 1, // non value, clicking on it does nothing
it: [{ c: 'file1' }, { c: 'file2' }, { c: 'file3' }]
},
{ c: 'Quit' }
],
meals: [],
help: [
{ c: 'View help' },
{ c: 'Feedback' },
{ c: '', cs: "o-litm", nv: 1 }, // horiz line
{ c: 'About' }]
};

$.when(cstorg.get('@Url.Action("GetMealsTreeImg", "Data")')).then(function (res) {
data.meals = res;
});

$.when(awe.dropmenu()).then(init);

function init() {
function openMenu(mitem, right) {
var prop = mitem.data('prop');

var dm1 = awe.dropmenu({
dataFunc: function () {
return data[prop];
},
minw: 150,
submenu: true, // tree data as submenu
asmi: prop !== 'meals' ? -1 : 0, // autosearch only for meals
itemFunc: site.imgItem,
select: function (item) {
awe.flash($('#log1').html('click on ' + item.c));
}
});

dm1.open({ opener: mitem, right: right });
return dm1;
}

// open on click menu
$('#menu1').on('click', '.mitem',
function (e) {
var mitem = $(e.target);
openMenu(mitem);
});

// open on hover menu
awem.hovMenu({
hover: $('#menuHov1').find('.mitem'),
open: openMenu
});

// open on hover side menu
awem.hovMenu({
hover: $('#sideMenu'),
hsel: '.smitem',
open: function (opener) { return openMenu(opener, true); }
});
}
});
</script>

Main menu with a links

File
Other
Dropmenu/Index.cshtml
<script>
$(function () {
var data = {
file: [
{ c: 'Home', k: '' },
{ c: 'About', k: 'Home/About' },
{
c: 'Grid demos',
nv: 1, // non value
it: [
{ c: 'Overview', k: 'GridDemo' },
{ c: 'Filtering', k: 'GridDemo/Filtering' },
{ c: 'Inline Editing', k: 'GridInlineEditDemo' }]
}
],
other: [
{ c: 'aweui', k: 'aweui' },
{ c: 'Mailbox', k: 'MailboxDemo' },
{ c: 'Cascade', k: 'MultipleLevelCascadingDemo' },
{ c: '', cs: "o-litm", nv: 1 }, // horiz line
{ c: 'Popup', k: 'PopupDemo' }]
};

$.when(awe.dropmenu()).then(init);

function init() {
// open on hover menu
awem.hovMenu({
hover: $('#linkMenu').find('.mitem'),
open: openMenu
});
}

function openMenu(mitem) {
var prop = mitem.data('prop');

var dm = awe.dropmenu({
dataFunc: function () {
return data[prop];
},
minw: 200,
submenu: true, // tree data as submenu
asmi: -1, // no search
clss: "amenu", // popup div class, .amenu in site.css makes the a occupy the whole li
itemFunc: function (item) {
return item.k != null ? '<a href="' + document.root + '/' + item.k + '">' + item.c + '</a>' : item.c;
// document.root is set in _Layout.cshtml
}
});

dm.open({ opener: mitem });
return dm;
}
});
</script>

<div id="linkMenu">
<div class="mitem" data-prop="file">File</div>
<div class="mitem" data-prop="other">Other</div>
</div>

Dropmenu with tree data

click here
Open a dropmenu on click. The menu data has a tree structure, allowing nodes to be expanded or collapsed
Dropmenu/Index.cshtml
<div id="areaTree1" class="area">
<div class="msg">click here</div>
</div>
<script>
$(() => {
const divArea = $('#areaTree1');
const msg = divArea.find('.msg');

divArea.on('click', (e) => {
awe.dropmenu({
dataFunc: () => [
{ k: 1, c: 'Item 1' },
{
k: 2,
c: 'Item 2',
nv: true, // non-value
it: [
{ k: 11, c: 'Item 11' },
{ k: 12, c: 'Item 12' },
{ k: 13, c: 'Item 13' },
{
k: 14,
c: 'Item 14',
it: [{ k: 141, c: 'Item 141' }]
}
]
},
{ k: 3, c: 'Item 3' }
],
select: (item) => msg.html(`You selected ${item.c}`),
clp: true, // Collapsible menu
autoOpen: {
xy: { x: e.clientX, y: e.clientY } // Positioning by cursor
}
});
});
});
</script>

Autocomplete in textarea

A textarea enhanced with an autocomplete dropmenu. As the user begins typing, a dropdown menu appears, suggesting relevant completions based on predefined data.
Shared/Demos/AutocInTxta.cshtml
<textarea id="text1" style="width: 100%" placeholder="try mango onion banana"></textarea>
<script>
$(function () {
let useAt = false;
let minLen = 1;
const txt = $('#text1');
let items = [];
let word = '';

// Fetch data
$.get('@Url.Action("GetAllMeals", "Data")', (res) => items = res);

awe.dropmenu({
dataFunc: () => items,
positionElm: txt, // position dropdown at elm
select: (item) => replaceInTexarea(txt[0], `${useAt ? '@@' : ''}${item.c}`, word), // action on select
closeIfNoRes: true, // Close when search has no results
srctxt: txt, // elm that will trigger the search and open the menu
getSearchTerm: getSearchTerm, // get search term at Caret without @@ symbol
showCheckmarkOnMatch: true // shows checkmark when search matches an item
});

function getSearchTerm() {
word = getCaretWord(txt[0]);
let mlen = minLen + (useAt? 1: 0);

if (word.length < mlen) return;

if(useAt)
{
if(!word.startsWith('@@')){
return;
}

return word.substring(1);
}

return word;
}

// settings
$('#chkUseAt').on('change', function () {
useAt = $(this).val() === 'true';
});

$('#txtMinLen').on('change', function () {
minLen = Number($(this).val());
});

$('#chkFstart').on('change', function () {
fstart = $(this).val() === 'true';
init();
});
});

function getCaretWord(el) {
// textarea autocomplete
function getWordAtPos(s, pos) {
var preText = s.substring(0, pos);
if (preText.indexOf(" ") > 0 || preText.indexOf("\n") > 0) {
var words = preText.split(" ");
words = words[words.length - 1].split("\n");
return words[words.length - 1]; // return last word
}
else {
return preText;
}
}

function getCaretPos(ctrl) {
var caretPos = 0;
if (document.selection) {
ctrl.trigger('focus');
var sel = document.selection.createRange();
sel.moveStart('character', -ctrl.value.length);
caretPos = sel.text.length;
}
else if (ctrl.selectionStart || ctrl.selectionStart === '0') {
caretPos = ctrl.selectionStart;
}

return caretPos;
}

var pos = getCaretPos(el);
return getWordAtPos(el.value, pos);
}

function replaceInTexarea(t, text, word) {
if (t.setSelectionRange) {
var sS = t.selectionStart - word.length;
var sE = t.selectionEnd;
t.value = t.value.substring(0, sS) + text + t.value.substr(sE);
t.setSelectionRange(sS + text.length, sS + text.length);
t.focus();
}
else if (t.createTextRange) {
document.selection.createRange().text = text;
}
}
</script>



Comments