I have following JS:
$("#search").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Home/GetCompanyNames",
dataType: "json",
data: "searchterm=" + request.term,
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
LogoUrl: item.LogoUrl,
InternetName :item.InternetName,
Name: item.Name
};
}));
}
});
},
minLength: 1
}).data("autocomplete")._renderItem = function (ul, item) {
var innerHtml = '<div class="image" style="float: left; margin-right: 35px;"><img src="' + item.LogoUrl + '"></div><div class="label">' + item.Name + '</div></div>';
return $("<li></li>")
.data("item.autocomplete", item)
.append(innerHtml)
.appendTo(ul);
};
});
which renders this
This is a suggestion dropdown which shows when I enter any character in textbox like ib in this case,
Everything is working fine but there is only one problem when I click any item of dropdown with mouse it take me to the url which is written in its anchor tag, I want that if I scroll down with and press enter on some item it will do the same currently it's not doing anything when I press enter on a item of dropdown.
Take a look at this jqFAQ.com topic, this will help you to navigate to the url on selection made by both mouse click and pressing enter. There are few more autocomplete related FAQs too.
Try adding a keyup handler to the a element in your returned list items. You should be able to do that by modifying the _renderItem function:
._renderItem = function (ul, item) {
var div = $('<div />'), //building using DOM elements, rather than HTML string.
liContainer = div.clone().addClass('list_item_container').css('height', '60px'),
img = $('<img />').attr('src', item.LogoUrl),
imgContainer = div.clone().addClass('image').css({
"float": "left",
"margin-right": "35px"
}),
divLabel = div.clone().addClass('label').text(item.Name),
a = $('<a />').attr('href', '/Store/' + item.InternetName);
imgContainer.append(img);
liContainer.append(imgContainer).append(divLabel);
a.append(liContainer);
a.on('keyup', function (e) { //add keyup handler to navigate to new URL on [Enter]
if (e.which === 13) {
window.location.href = $(this).attr('href');
}
});
return $("<li></li>")
.data("item.autocomplete", item)
.append(a)
.appendTo(ul);
};
Related
I have a custom button in summernote that has a dropdown of items "one", "two", "three" when I click on for example the text "one" the text is added at the start which is fine. But then when I click on "two" afterwards the text is also added at the start which produces this result.
twoone
I would like to have the following result
one
two
Update when I use this line
context.invoke("editor.pasteHTML", context.modules.editor.$editable[0].innerText ? "<br>" + $(this).html() : $(this).html() );
instead of
context.invoke('editor.insertText', $(this).html());
I get the following result wihch is better but the order is still incorrect
two
one
Here you can fiddle with my code
https://stackblitz.com/edit/angular-summernote-demo-n7xn2n?file=src%2Fapp%2Fapp.component.ts
Otherwise here is my code for the button that inserts the text
function customButtonGenerator(lstQuoteComments, title) {
return function (context) {
const ui = ($ as any).summernote.ui;
var i;
var listHtml = '';
for (i = 0; i < lstQuoteComments.length; i++) {
listHtml += '<li>' + lstQuoteComments[i] + '</li>';
}
const button = ui.buttonGroup([
ui.button({
className: 'dropdown-toggle',
contents:
'<i class="fa fa-comments text-primary"/><span id="summernot-caret" class="caret text-primary"></span>',
//tooltip: 'Comments', //Not working when howver over it top is not defined
data: {
toggle: 'dropdown',
},
}),
ui.dropdown({
className: 'drop-default summernote-list',
contents:
'<div id="container-comentario"><div id="dialog" title="' +
title +
'" ><h1 class="header-comentario">' +
title +
'</h1><ul id="summernote-list"><ul>' +
listHtml +
'</ul></div></div>',
callback: function ($dropdown) {
$dropdown.find('li').each(function () {
$(this).click(function () {
context.invoke('editor.insertText', $(this).html());
});
});
},
}),
]);
return button.render();
};
}
Thank you for your help.
As far as I can see, these answer don't quite get the question right.
You should append the button content to the existing content like this:
Example blitz - https://stackblitz.com/edit/angular-summernote-demo-ycvten?file=src%2Fapp%2Fapp.component.ts
Main code snippet:
...
callback: function ($dropdown) {
$dropdown.find('li').each(function () {
$(this).click(function () {
let newHtml = context.modules.editor.$editable[0].innerHTML
if (newHtml !== '') {
newHtml += '<br>'
}
newHtml += $(this).html()
context.invoke('code', newHtml)
})
})
}
...
I'll have a look if there is a way to keep track of the current cursor position, I think there must be. I'l update if that's possible, rather than just adding to the end.
You can try to replace this line in customButtonGenerator function:
context.invoke('editor.insertText', $(this).html());
With:
context.invoke('editor.pasteHTML', $(this).html());
OR
context.invoke('editor.pasteHTML', '<div>' + $(this).html() + '</div>');
Replace this line
context.invoke('editor.insertText', $(this).html());
with
context.invoke("code", context.modules.editor.$editable[0].innerHTML + '<br>' + $(this).html());
This will solve the issue.
I added mcautocomplete to my slickgrid. if I check some of the checkboxes mcautocomplete table is not visible anymore on slickgrid. Please check the pic.
How do i make sure that my autocomplete options are visible over my slickgrid?
$.widget('custom.mcautocomplete', $.ui.autocomplete, {
_create: function () {
this._super();
this.widget().menu("option", "items", "> :not(.ui-widget-header)");
},
_renderMenu: function (ul, items) {
var self = this,
thead;
if (this.options.showHeader) {
table = $('<div class="ui-widget-header" style="width:100%"></div>');
$.each(this.options.columns, function (index, item) {
table.append('<span style="font-weight:bold;background-color:#EEE8AA;padding:0 4px;float:left;width:' + item.width + ';">' + item.name + '</span>');
});
table.append('<div style="clear: both;"></div>');
ul.append(table);
}
$.each(items, function (index, item) {
self._renderItem(ul, item);
});
},
_renderItem: function (ul, item) {
var t = '',
result = '';
$.each(this.options.columns, function (index, column) {
t += '<span style="background-color:#ADD8E6;padding:0 4px;float:left;width:' + column.width + ';">' + item[column.valueField ? column.valueField : index] + '</span>'
});
result = $('<div></div>')
.data('ui-autocomplete-item', item)
.append('<div class="mcacAnchor">' + t + '<div style="clear: both;"></div></div>')
.appendTo(ul);
return result;
}
});
You can try z-index (this can be complex and all comes down to the priority of the container elements), but I have found that the structure of some javascript controls are simply not compatible with SlickGrid.
(not saying that mcautocomplete is not compatible, with the right tweaks, but it MAY not be).
For example, I was using 'chosen' for dropdowns, but as it used table elements that would not play well with the slickgrid infrastructure, I had to abandon that for 'select2'. There is a 'select2' example in the 6pac github repository, and I think select2 has an autocorrect mode. Might be worth a try.
I've defined a jQueryUI menu with id leftmenu and on its list elements, I have defined a function on clicking one item, as follows:
$('#leftmenu>li').click(function () {
var clickedId = this.id;
$.ajax({
type: "POST",
cache: false,
url: "/Session/Index/",
success: function (result) {
if (result.length > 0)
{
performListItemAction(clickedId);
}
else
{
window.location.href = '/Home/Index/'
}
}
});
});
This works fine, but now I want to change it so that instead of the click on the menu item, I want to capture focus and selection on that item in a more general way, such as using the keyboard. Currently, I can navigate through the menu using the up and down keys on the keyboard, but the inner code does not get called. I know this is because it is only supposed to happen on click, but the same thing happpened when I tried activate and focus in place of the click as well.
How can I get it to perform the same behavior as click in a more general way that captures selection and enter of the menu item?
Thank you.
This should be done in the select event. This way it catches both click or select from focused keyboard actions.
Example: https://jsfiddle.net/Twisty/v671x6ns/
jQuery
$(function() {
$('#leftmenu').menu({
select: function(e, ui) {
var selectId = ui.item.attr("id");
$.ajax({
type: "POST",
cache: false,
url: "/Session/Index/",
success: function(result) {
if (result.length > 0) {
performListItemAction(selectId);
} else {
window.location.href = '/Home/Index/'
}
}
});
console.log(e.type + " event, ID: " + selectId);
}
});
});
I am trying to use the Marvel API to display a list of events a character has been involved in. Here is my script:
$(".heroSubmit").click(function() {
var heroName = $(".hero").val();
$.getJSON("http://gateway.marvel.com:80/v1/public/characters?name=" + heroName + "&apikey=", function (json) {
$(".name").html(json.data.results[0].name);
$(".description").html(json.data.results[0].description);
$(".image").attr("src", json.data.results[0].thumbnail.path + "/detail.jpg");
$(".comics").html(json.data.results[0].comics.available);
$.each( json.data.results[0].events.items, function(i, item) {
$(".events").html("<li>" + item.name + "</li>");
});
});
Everything works fine except for the each section. Right now, it is only displaying the last event name (item.name). I need for all of the events to display.
This is because you rewrite events' content in each iteration. To avoid this replace html() with append():
$.each( json.data.results[0].events.items, function(i, item) {
$(".events").append("<li>" + item.name + "</li>");
});
I'm a newbie to jQuery and jQuery mobile.
I followed a few samples and documentations and created the following code:
function initListByUrl(id, requestUrl) {
$.ajax({
url: requestUrl,
type:'GET',
dataType:'json',
success: function(data) {
var items = []
$.each(data, function(i, elem) {
items.push('<li id="cat_li_'+i+'">' + elem.name + '</li>');
});
id.html(items).listview('refresh');
}
});
}
$(document).on("click", '[id^=cat_li]', function(event, ui) {
console.log(3);
})
I need to have the elem event from the $.ajax available in the context of the click event
This is because the elem object holds a field that is relevent when the item is clicked.
How should I do it?
EDIT
just to clarify.
the initListByUrl functions is called in document-ready. It builds a list view by the retrieved json object which contains an array.
if I had elem in the context of the on-click event I would have done something like this:
$(document).on("click", '[id^=cat_li]', function(event, ui) {
call_some_function(elem.someField);
})
My issue is how do I have the appropriate elem object in the scope of the on-click event?
EDIT 2
This is my full code:
var stack = []
var site_url = 'http://localhost:3000';
$(function() {
initCategoriesList();
$("#places").on('pageinit', function() {
var category = stack.pop();
initPlacesList(category);
});
$("#place").on('pageinit', function() {
});
});
function initCategoriesList(id, requestUrl) {
$.ajax({
url: site_url + '/categories',
type:'GET',
dataType:'json',
success: function(data) {
var items = []
$.each(data, function(i, elem) {
items.push('<li id="cat_li_'+i+'">' + elem.name + '</li>');
});
$("#categories_ul").html(items).listview('refresh');
}
});
}
function initPlacesList(category_id) {
$.ajax({
url: site_url + '/business_places/category/' + category_id,
type:'GET',
dataType:'json',
success: function(data) {
var items = []
$.each(data, function(i, elem) {
items.push('<li id="place_li_'+i+'">' + elem.name + '</li>');
$("#places_ul").html(items).listview('refresh');
var element = $("#place_li_" + i)[0];
$.data(element, "object", elem);
});
$("#places_ul").html(items).listview('refresh');
}
});
}
$(document).on("click", '[id^=cat_li]', function(event, ui) {
stack.push(event.target.innerText);
})
$(document).on("click", '[id^=place_li]', function(event, ui) {
var place = $.data(this, "object");
alert(place.name);
})
var place = $.data(this, "object");
ends up having undefined
Your best bet is going to be to create custom data attributes inside the li element to be accessed at a later time. Push the data you need to these custom attributes. Example:
items.push('<li id="cat_li_'+i+'" data-custom-cool="' + elem.someData + '">' + elem.name + '</li>');
Now, you can pull out the data as you need it with this inside your click handler.
$(this).data("custom-cool"); //this is equiv to elem.someData .
Or, if you have bigger data, you can store the object with the element with $.data:
$.each(data, function(i, elem) {
items.push('<li id="cat_li_'+i+'">' + elem.name + '</li>');
});
id.html(items).listview('refresh');
var element = $("#cat_li_" + i)[0]; //cant use jQ object
$.data(element, "object", elem); //assign object
});
Now your click handler should be able to access the object like so (inside handler):
console.log($.data(this, "object").objProperty); //replace objProperty with your property to get.
Demo: http://jsfiddle.net/tymeJV/vx8Xt/1/ Click on "testdiv" and see the console.
I think the problem is with id.html(items), .html() doesn't accept an array.
id.html(items.join('')).listview('refresh');
Also to fix your other problem, you should use classes instead of ids :
function initListByUrl(id, requestUrl) {
$.getJSON(requestUrl, function(data) {
var items = []
$.each(data, function(i, elem) {
items.push('<li class="cat">' + elem.name + '</li>');
});
id.html(items).listview('refresh');
});
}
$(document).on("click", '.cat a', function(event, ui) {
console.log(3);
});
Like ajax is asynchronous by default, you have two options:
You can make the ajax request synchronous by switching the option async to false - for more details, see jQuery.ajax() API
You can save the elem in a global variable and use it in the onclick-handler
Maybe it would also be helpful if you tell us, when the function initListByURL() is executed.
You should move the event binding into the success function, after all item in the list has been attached to Document
success: function(data) {
var items = []
$.each(data, function(i, elem) {
items.push('<li id="cat_li_'+i+'">' + elem.name + '</li>');
});
id.html(items).listview('refresh');
// move your click event handling here
}