jquery combobox wont close when clicking on page - jquery-ui

I created a jquery combobox which even when I open it using the button I want it to close when clicking on the page body. I'm using jQuery v1.10.1 and jQuery UI v1.10.3. When I originally wrote it I was using v111 and I had an onclick in the body to close it but when I upgraded the auto-complete never stayed open. I tried to make a jfiddle http://jsfiddle.net/abakoltuv/Lmbdn/ but the button doesn't work at all.
local css:
.textbox, input.combobox {
border: 1px solid #666666;
color: black;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
}
span.combobox {
border-bottom: 1px solid #666666;
border-right: 1px solid #666666;
border-top: 1px solid #666666;
cursor: pointer;
display: inline-block;
font-size: 10px;
height: 8px;
padding: 2px 2px 4px;
position: relative;
top: 1px;
width: 10px;
}
<b>Brand</b><br />
<input type="text" onChange="setChangedFlag()" field="BRAND_ID" value="" id="BRAND_ID_display" name="BRAND_ID_display" size="22" class="combobox" style="width: 121px;"><span onClick="click_combobox_open('BRAND_ID_display')" class="combobox">▼</span>
<br /><input type="text" value="" id="BRAND_ID" name="BRAND_ID" style="background-color:#CCCCCC" class="textbox" size="22">
<script language="javascript" type="text/javascript">
<!--
$(document).ready(function() {
setup_combobox();
});
function setup_combobox()
{
var largest_size;
var data = [{"id":"1","value":"Able Planet"},{"id":"86","value":"Able Planet 123"},{"id":"2","value":"Acecad"},{"id":"3","value":"Action Life Media"},{"id":"4","value":"Adobe"},{"id":"5","value":"Bose"},{"id":"6","value":"Canon"},{"id":"7","value":"Delkin"}];
$("input.combobox").autocomplete({
html: 'html',
minLength: 0,
source: data ,
select: function(event, ui) {
if (ui.item) {
var width1 = $('#'+this.id).width();
$('#'+this.id).width((ui.item.value.length * 2/3) + 'em');
var width2 = $('#'+this.id).width();
if(width1 > width2)
$('#'+this.id).width(width1);
$('#'+this.id.substring(0, this.id.length - 8)).val(ui.item.id);
};
}
});
}
function click_combobox_open(display_ID)
{
var width1 = $('#'+display_ID).width();
$('#'+display_ID).width(($('#'+display_ID).val().length * 2/3) + 'em');
var width2 = $('#'+display_ID).width();
if(width1 > width2)
$('#'+display_ID).width(width1);
else
$('#'+display_ID).width(width2);
if(!$('#'+display_ID).autocomplete('widget').is(':visible'))
{
$('#'+display_ID).autocomplete('search','');
}
else
{
$('#'+display_ID).autocomplete('close');
}
}
//-->
</script>
Thanks
Aba

I finally figured it out I just needed to focus on the text box after opening it.
function click_combobox_open(display_ID)
{
var width1 = $('#'+display_ID).width();
$('#'+display_ID).width(($('#'+display_ID).val().length * 2/3) + 'em');
var width2 = $('#'+display_ID).width();
if(width1 > width2)
$('#'+display_ID).width(width1);
else
$('#'+display_ID).width(width2);
if(!$('#'+display_ID).autocomplete('widget').is(':visible'))
{
$('#'+display_ID).autocomplete('search','');
**$('#'+display_ID).focus();**
}
else
{
$('#'+display_ID).autocomplete('close');
}
}

Related

The script is not output properly

can someone please help me with this? The problem is explained in the video.
https://www.loom.com/share/dba701f22d1c42d38617d9b835d713e4
Here is what I am trying to do, on the input field we will add a youtube video URL and when clicked on the Generate Embed Code button it should output the embed code inside the text aria, do you know why its not working?
<div class="youtube-iframe-generator">
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed&display=swap" rel="stylesheet">
<script>
window.onload = setup;
function setup() {
document.getElementById("button").addEventListener("click", go);
document.getElementById("copy-button").addEventListener("click", copy);
}
function setStatus(status, error = false) {
var helpText = document.getElementById("help-text");
helpText.innerText = status;
if (error) {
helpText.style.color = "darkred";
} else {
helpText.style.color = "#227300";
}
}
function go() {
var videoUrl = document.getElementById("input").value;
var videoIdExtractor = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;
var result = videoIdExtractor.exec(videoUrl);
var EmbedCode = document.getElementById("EmbedCode");
var copyButton = document.getElementById("copy-button");
if (!result) {
EmbedCode.innerHTML = "";
copyButton.disabled = true;
setStatus("Error: Invalid YouTube URL", true);
return;
}
var videoId = result[1];
var finalLink = "https://www.youtube.com/embed/" + videoId;
var imgLink = "https://img.youtube.com/vi/"+videoId+"/maxresdefault.jpg";
var iframe = '<iframe class="youtube-iframe" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{position: absolute;content: '\f04b';top: 50%;left: 50%;background-color: #6c6cfe;width: 68px;height: 44px;margin-left: -34px;margin-top: -24px;font-size: 30px;color: #fff;text-align: center;line-height: 43px;z-index: 5;border-radius: 6px;}a{display:block;height:100%;}</style><img src="'+imgLink+'" alt="Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"><span>▶</span>" frameborder="0" style="aspect-ratio: 16 / 9; width: 100%;" allow="accelerometer; autoplay; encrypted-media; gyroscope;" allowfullscreen></iframe>';
EmbedCode.disabled = false;
copyButton.disabled = false;
EmbedCode.value = iframe;
setStatus("Success! Click the 'Copy' button to copy the embed code.");
}
function copy() {
var EmbedCode = document.getElementById("EmbedCode");
EmbedCode.select();
document.execCommand("copy");
setStatus("Embed code copied to clipboard!");
}
}
</script>
<div class="title">Enter your Youtube URL: <span class="sub">(Scroll down for instructions)</span>
<style>
.youtube-iframe-generator {
font-family: 'Roboto Condensed', sans-serif;
width:96.9%;
}
.title {
font-size: 1.6em;
margin: 15px 0 10px;
}
.sub {
font-size: 0.5em;
color: #444;
vertical-align: middle;
}
#copy-button,
#button {
display: block;
font-family: 'Roboto Condensed', sans-serif;
font-size: 1.2em;
padding: 10px 18px;
margin: 15px auto;
border: none;
border-radius: 3px;
background: #598cff;
color: #ffffff;
cursor: pointer;
box-shadow: 0 2px 3px 0px #b5b5b5;
transition: background 200ms;
}
#copy-button:hover,
#button:hover {
background: #6b99ff;
}
#copy-button:active,
#button:active {
background: #598cff;
box-shadow: 0 2px 3px -1px #b5b5b5;
}
#input{
font-size: 1.1em;
display: block;
width: 100%;
padding: 10px;
border: 1px solid #b5b5b5;
border-radius: 3px;
}
#EmbedCode {
font-size: 1.1em;
display: block;
width: 100%;
padding: 10px;
border: 1px solid #b5b5b5;
border-radius: 3px;
resize: vertical;
overflow: auto;
}
#help-text {
font-weight: 600;
margin: 10px;
}
</style>
</div>
<input id="input" type="text" placeholder="https://www.youtube.com/watch?v=h4iRMtQBGAk">
<button id="button">Generate Embed Code</button>
<div class="title">Embed Code:</div>
<textarea id="EmbedCode" type="text" readonly="" disabled=""></textarea>
<button id="copy-button" disabled> <i class="fa-regular fa-clipboard"></i> Copy Embed Code</button>
<div id="help-text"></div>
</div>

jQuery UI draggable locking divs

I wrote some kind of that: http://jsfiddle.net/py3DE/203/ but when element is dragged into proper container, we can override it by dragging other div into its area. Could you tel me how i can block dragged elements, and if someone will try to override any element, div returns back into area with undragged divs?
if (!ui.draggable.closest('.empty').length) item = item.draggable()'
There is a simple way to do this. Basically, we'll remove the class empty and use the disable method.
Working Example: http://jsfiddle.net/Twisty/5rdxmp4p/
Minor CSS Change
.filled .item .closer {
display: block;
}
Drop Function
drop: function(ev, ui) {
if ($(this).hasClass("empty")) {
$(this).removeClass("empty").addClass("filled");
$(this).droppable("disable");
} else {
return false;
}
var item = ui.draggable;
if (!ui.draggable.closest('.empty').length) item = item.draggable(); // if item was dragged from the source list - clone it
this.innerHTML = ''; // clean the placeholder
item.css({
top: 0,
left: 0
}).appendTo(this); // append item to placeholder
}
Swapping the class allows the X button to appear. We then run the disable method to ensure that this specific item will no longer accept a dragged item. If the user drags an item to this spot, it is then reverted.
Update
Using Sortable: http://jsfiddle.net/Twisty/5rdxmp4p/2/
HTML
<div id="dragItems" class="source">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
</div>
<div id="sortItems" class="target">
</div>
CSS
body {
background: #fff;
}
.source,
.target {
margin: 20px;
min-height: 190px;
width: 400px;
border: 1px solid green;
}
.target {
border: 1px solid blue;
}
.item {
height: 20px;
margin: 5px;
padding: 5px;
border: 1px solid gray;
background-color: #cd8;
position: relative;
}
.closer {
float: right;
width: 20px;
height: 20px;
border: 0;
background-color: transparent;
}
.closer:hover {
background-color: transparent;
border: 0;
}
.empty {
height: 30px;
margin: 5px;
background: #eee;
border: 1px dashed #999;
}
.highlight {
border: 1px solid red;
background: #fff;
}
.highlight .item {
opacity: 0.3;
}
.ui-draggable-dragging {
z-index: 99;
opacity: 1 !important;
width: 378px;
}
jQuery
$(function() {
$("#sortItems").sortable({
axis: "y",
items: "> div",
placeholder: "empty",
dropOnEmpty: true,
stop: function(e, ui) {
var $it = ui.item;
if ($it.find(".closer").length == 0) {
var closeBtn = $("<span>", {
class: "closer"
});
$it.append(closeBtn);
closeBtn.button({
icon: "ui-icon-close",
label: "Close",
showLabel: false
}).click(function(ev) {
console.log("[INFO]: Closing ", $it);
$it.fadeTo(200, 0.0, function() {
$it.remove();
$("#sortItems").sortable("refresh");
});
});
}
}
});
$("#dragItems .item").draggable({
connectToSortable: "#sortItems",
revert: "invalid"
});
$("#sortItems").disableSelection();
});

Is there any knockout plugin for showing a nested context menu?

Is there any knockout plugin for showing a nested context menu?
My specific need is to show a contextmenu for list items, that has a "SendTo" menuitem and the possible subItems have to be set at runtime.
In the apparent lack of suitable plugins I went for the more direct Knockout approach. I'm sure the code can be more elegantly packed in a custom binding but this is the solution I came up with, if anyone would need something similar. In my case the menu is build each time it's opened because it makes sense in my usecase. I'm sure the code can easily be customized to some other scenarios.
So... The markup:
<li data-bind="event: { contextmenu: $root.showSendToMenu }/>
is used to show the popup menu, for an item on a right click.
And the markup for the menu itself:
#*The send to popup menu*#
<ul class="context-menu" data-bind="visible:contextMenu.activeElement, style:{left:contextMenu.left, top:contextMenu.top}, template: { name: 'menu-item-template', foreach: contextMenu.items }, event: { mouseleave: contextMenu.contextMouseLeave }"></ul>
#*Template for a menu item*#
<script type="text/html" id="menu-item-template">
<li>
<!-- ko if: children -->
<span data-bind="text:text"></span>
<ul data-bind="template: { name: 'menu-item-template', foreach: children }"></ul>
<!-- /ko -->
<!-- ko if: !children -->
<!-- /ko -->
</li>
</script>
And in the viewModel, I have the following code (TypeScript):
contextMenu = { activeElement: ko.observable(null), left: ko.observable('0px'), top: ko.observable('200px'), items: ko.observableArray(<MenuItem[]>[]), contextMouseLeave : () => { this.contextMenu.activeElement(null); } };
showSendToMenu = (item, event) => {
//Set menu position
this.contextMenu.left(event.pageX + 'px');
this.contextMenu.top(event.pageY + 'px');
//Build the menu
var lines = [];
for (var i = 0; i < this.prodLines().length; i++) {
var line = this.prodLines()[i];
if (line.lists().length > 0) {
var lists = [];
for (var j = 0; j < line.lists().length; j++) {
var list = line.lists()[j];
lists.push(new MenuItem(list.name(), null, list));
}
lines.push(new MenuItem(line.name + "->", lists, line));
}
}
var items = [new MenuItem("SendTo ->", lines)];
//Set the menu
this.contextMenu.items(items);
this.contextMenu.activeElement(item);
}
onContextClick = (menuItem: MenuItem) => {
var sendToList = menuItem.tag;
var item = this.contextMenu.activeElement();
this.dropToList(item, sendToList);
//Hide the menu
this.contextMenu.activeElement(null);
}
And lastly, I used this piece of css to make the menu behave menu-like:
.context-menu {
position: absolute;
padding: 0;
margin: 0;
z-index: 1030;
background-color: #dddddd;
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
min-width:100px;
border: 1px solid gray;
text-decoration:none;
}
.context-menu ul {
position: absolute;
z-index: 1031;
line-height: 1.6;
padding: 0;
margin: 0;
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
display:none;
left:98px;
min-width:100px;
top:-1px;
background-color:#dddddd;
border: 1px solid gray;
text-decoration:none;
}
.context-menu li {
position:relative;
}
.context-menu li:hover > ul {
display:block;
}
.context-menu li {
padding: 4px 20px;
margin: 0;
list-style-type: none;
cursor: pointer;
white-space: nowrap;
color: #333333;
}
.context-menu ul > li:hover {
background-color: white;
text-decoration:underline;
}
I hope this will help someone

Trouble with jQuery UI draggable, droppable, and sortable combo

Seems like I can choose only 2. :)
Here's where I'm at. I can sort the droppable divs and I can drag the ui-draggable, but I cannot drop ui-draggable into the ui-widget-header divs. :/
HTML:
<div class="large-9 small-9 columns">
<div id="paginationPageDisplay" class="dropme paginationContainer ui-sortable">
<div class="droppable ui-widget-header">
<div class="droppable ui-widget-header">
</div>
</div>
<div class="large-3 small-3 columns">
<div id="paginationAdDisplay" class="paginationContainer">
<div class="adThing ui-draggable">1/4</div>
<div class="adThing ui-draggable">1/2</div>
<div class="adThing ui-draggable">Full Page</div>
</div>
</div>
CSS:
.paginationContainer {
height: 1500px;
margin-right: 1px;
border: 1px solid #CCCCCC;
}
.adThing {
display: inline-block;
width: auto;
height: auto;
padding: 8px 15px;
border: 1px solid #ccc;
text-align: center;
background: #eee;
}
.dropme {
display: inline-block;
width: auto;
height: auto;
overflow: hidden;
margin-top: 20px;
}
.droppable {
height: 120px;
width: 90px;
padding: 2px;
margin: 10px 3px;
background: #F9F9F9;
border: 1px solid #CCCCCC;
float: right;
}
JS:
$('.adThing').draggable({
cursor: 'pointer',
connectWith: '.dropme',
helper: 'clone',
opacity: 0.5,
zIndex: 10
});
$('.dropme').sortable({
connectWith: '.dropme',
cursor: 'pointer'
});
$('.droppable').droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
$("#paginationLoadButton").click(function() {
var pageCount, i, $pageDisplay = $("#paginationPageDisplay"), pageWidget;
$pageDisplay.html('');
pageCount = $("#paginationPageCount").val();
for (i=1; i<=pageCount; i++) {
pageWidget = '<div class="droppable ui-widget-header">' + i + '<p></p></div>';
$pageDisplay.html($pageDisplay.html() + pageWidget);
}
});
The problem was that I was binding droppable on document ready but those elements are generated by the button click. I moved the droppable bind into the button click event and it's resolved.
$("#paginationLoadButton").click(function() {
var pageCount, i, $pageDisplay = $("#paginationPageDisplay"), pageWidget;
$pageDisplay.html('');
pageCount = $("#paginationPageCount").val();
for (i=1; i<=pageCount; i++) {
pageWidget = '<div class="droppable ui-widget-header">' + i + '<p></p></div>';
$pageDisplay.html($pageDisplay.html() + pageWidget);
}
$('.droppable').droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});

JCarousel adding blogpost instead of html

is it possible to add my blogposts to JCarousel instead of a html code? It should look like this:
=> EXAMPLE
On this site the content is just html, but I want my blogpost to show off.
Let's say I wrote 5 blogposts, so the Slider must show me the 5 blogposts.
Hope someone can help me out!
Greetings
Nico
You'll need to create a macro (xslt or razor) that will display your blog post nodes and then target them with jquery to load the jcarousel. Below is an example of a razor script that does this using the code from the example you referenced:
#using umbraco.MacroEngines
#inherits DynamicNodeContext
#try
{
<script type="text/javascript" src="http://www.fdp-bw.de/jcarousel/lib/jquery-1.2.3.pack.js"></script>
<script type="text/javascript" src="http://www.fdp-bw.de/jcarousel/lib/jquery.jcarousel.pack.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.fdp-bw.de/jcarousel/lib/jquery.jcarousel.css" />
<link rel="stylesheet" type="text/css" href="http://www.fdp-bw.de/jcarousel/skins/tango/skin.css" />
<style type="text/css">
/**
* Additional styles for the controls.
*/
.jcarousel-control {
margin-bottom: 10px;
text-align: center;
}
.jcarousel-control a {
font-size: 75%;
text-decoration: none;
padding: 0 5px;
margin: 0 0 5px 0;
border: 1px solid #fff;
color: #eee;
background-color: #4088b8;
font-weight: bold;
}
.jcarousel-control a:focus,
.jcarousel-control a:active {
outline: none;
}
.jcarousel-scroll {
margin-top: 10px;
text-align: center;
}
.jcarousel-scroll form {
margin: 0;
padding: 0;
}
.jcarousel-scroll select {
font-size: 75%;
}
#mycarousel-next,
#mycarousel-prev {
cursor: pointer;
margin-bottom: -10px;
text-decoration: underline;
font-size: 11px;
}
</style>
<script type="text/javascript">
/**
* We use the initCallback callback
* to assign functionality to the controls
*/
function mycarousel_initCallback(carousel) {
jQuery('.jcarousel-control a').bind('click', function () {
carousel.scroll(jQuery.jcarousel.intval(jQuery(this).text()));
return false;
});
jQuery('.jcarousel-scroll select').bind('change', function () {
carousel.options.scroll = jQuery.jcarousel.intval(this.options[this.selectedIndex].value);
return false;
});
jQuery('#mycarousel-next').bind('click', function () {
carousel.next();
return false;
});
jQuery('#mycarousel-prev').bind('click', function () {
carousel.prev();
return false;
});
};
// Ride the carousel...
jQuery(document).ready(function () {
jQuery("#mycarousel").jcarousel({
scroll: 1,
visible: 1,
auto: 10,
wrap: "last",
initCallback: mycarousel_initCallback,
// This tells jCarousel NOT to autobuild prev/next buttons
buttonNextHTML: null,
buttonPrevHTML: null
});
});
</script>
<div id="mycarousel" class="jcarousel-skin-tango">
<ul>
#foreach (var post in Model.AncestorOrSelf().Descendants("umbBlogPost"))
{
<li>
<h2>#post.Name</h2>
<div>#post.bodyText</div>
</li>
}
</ul>
<div class="jcarousel-control">
#for (int i = 0; i < Model.AncestorOrSelf().Descendants("umbBlogPost").Count(); i++)
{
#(i + 1)
}
</div>
</div>
}
catch (Exception e)
{
<!-- #e.ToString() -->
}
That will give you all of the posts. You may want to do some ordering and filtering and then get the top five or whatever:
var posts = Model.AncestorOrSelf().Descendants("umbBlogPost").OrderBy("PostDate desc").Take(5);

Resources