Drag and Drop between Two lists (List 2 only has sort) - jquery-ui

I am struggling to get the required functionality from my current code.
Two Lists (grid style) List 1 - List 2
List 1 items are draggable to list 2, NOT sortable, cloned (but then disabled as you can only add item once)
List 2 droppable, you can sort, entire item html copies over from list 1.
Code Pen script
$(function () {
$('.box').draggable({
appendTo: "body",
helper: "clone"
});
$("#sortable2").droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
accept: ":not(.ui-sortable-helper)",
drop: function (event, ui) {
//add first element when cart is empty
if ($(this).find('.placeholder').length > 0) {
$(this).find('.placeholder').remove();
$("<li></li>").text(ui.draggable.text()).appendTo(this);
} else {
//used as flag to find out if element added or not
var i = 0;
$(this).children("li").each(function () {
if ($(this).offset().top >= ui.offset.top) {
//compare
$("<li class='box'></li>").text(ui.draggable.text()).insertBefore($(this));
i = 1;
return false; //break loop
}
});
if (i !== 1) {
//if element dropped at the end of cart
$("<li class='box'></li>").text(ui.draggable.text()).appendTo(this);
}
}
}
})
$(function() {
$( "#sortable2" ).sortable({
placeholder: "highlight",
items: "li:not(#sortable1)",
sort: function () {
$(this).removeClass("ui-state-default");
}
});
});
});
//Display action in text
$(function DisplayWhatDropped() {
var area = "Area Dropped";
var item = "fId of the item";
$(".result").html(
"[Action] <b>" + item + "</b>" + " dropped on " + "<b>" + area + "</b>"
);
});
Any assistance would be greatly appreciated.

Related

jQuery ui- creating a handle for selectable

I'm looking to combine sortable and selectable and want to create something something similar to handle for selectable. So in other words, if I have a list and a div inside the list elements I would be able to select the list item by just clicking on the div. So just like the handle option for sortable.
Sortable code:
$("#list3").sortable({
handle:'.PageTreeListMove',
connectWith: ".droptrue",
helper: function (e, li) {
this.copyHelper = li.clone().insertAfter(li);
$(this).data('copied', false);
return li.clone();
},
stop: function () {
var copied = $(this).data('copied');
if (!copied) {
this.copyHelper.remove();
}
this.copyHelper = null;
}
});
$("#list4").sortable({
dropOnEmpty: true,
receive: function (e, ui) {
var i=0;
ui.sender.data('copied', true);
ui.item.html('' + ui.item.text() + '<span class="PageTreeListDelete"> </span>');
ui.item.attr('id',ui.item.id);
ui.item.removeAttr('style');
ui.item.addClass("added");
var identicalItemCount = $("#list4").children('li#'+ui.item.attr('id')).length;
if (identicalItemCount > 1) {
$("#list4").children('li#'+ui.item.attr('id')).first().remove();
}
}
}).disableSelection();
**Selectable code:
$("#list3").selectable({
selecting: function(e, ui) {
var curr = $(ui.selecting.tagName, e.target).index(ui.selecting);
selectedItems.push("<li id="+$(ui.selecting).attr('id')+" class='added'><a href>"+$(ui.selecting).text()+"</a><span class='PageTreeListDelete'> </span></li>");
if(e.shiftKey&&prev>-1) {
$(ui.selecting.tagName, e.target).slice(Math.min(prev, curr), 1 + Math.max(prev, curr)).addClass('ui-selected');
} else {
prev = curr;
}
},
cancel:'ui-selected'
});

jQuery UI menu inside a jqGrid cell

I have created a grid and customized a column to contain a jquery UI menu like in the Split Button example
Everything works fine except for the fact that the menu window appear inside the cell causing a bad visual effect, that is, the cell height increase to make room for the menu window.
Have a look at the following screenshot for a visual explanation (nevermind about the menu item in disabled state).
Is there any way way to make the menu window appear on top of the table element in term of z-index?
Thanks very much for your valuable help, community :)
EDIT as per comment request:
The code to create the splitbutton menu is the following. First the column model markup
{ name: 'act', index: 'act', width: 80, sortable: false, search: false, align: 'center',
formatter: function (cellvalue, options, rowObject) {
var markup = "<div>" +
"<div class='actionsButtonset'>" +
"<button class='dshbd_ConfirmMonth' rel='" + rowObject.UmltID + "' rev='" + rowObject.IsConfirmAvailable + "' plock='" + rowObject.IsPeriodLocked + "' alt='Confirm'>Confirm</button>" +
"<button class='btnSelectMenu' rev='" + rowObject.IsUmltLocked + "' " + ">Select</button>" +
"</div>" +
"<ul class='actionMenu'>" +
"<li><a class='dshbd_UnlockMonth' href='#' rel='" + rowObject.UmltID + "' alt='Unlock'>Unlock</a></li>" +
"</ul>" +
"</div>";
return markup;
}
}
Then, inside the gridComplete event I have the following code (please note that some code is needed to enable/disable menu items
var confirmMonthBtn = $('.dshbd_ConfirmMonth');
$.each(confirmMonthBtn, function (key, value) {
var button = $(this);
var umltID = button.attr('rel');
button.button().click(function (event) {
event.preventDefault();
});
var isPeriodLocked = (button.attr('plock') === 'true');
if (!isPeriodLocked) {
var isConfirmAvailable = ($(this).attr('rev') === 'true');
if (!isConfirmAvailable) {
button.button({ disabled: true });
}
} else {
button.button({ disabled: true });
}
});
var currentPeriod = GetCurrentPeriod();
var period = GetCurrentViewPeriod();
var isCurrent = false;
if (currentPeriod != null && period != null) {
isCurrent = period.PeriodID == currentPeriod.PeriodID;
}
var selectBtns = $('.btnSelectMenu');
$.each(selectBtns, function (key, value) {
var button = $(this);
button.button({ text: false, icons: { primary: 'ui-icon-triangle-1-s'} });
button.click(function (event) {
var menu = $(this).parent().next().show();
menu.position({
my: 'left top',
at: 'left bottom',
of: this
});
$(document).on('click', function () {
menu.hide();
});
return false;
});
$('div.actionsButtonset').buttonset();
var menuElement = button.parent().next();
menuElement.hide();
menuElement.menu({
select: function (event, ui) {
var umltID = ui.item.children().attr('rel');
event.preventDefault();
}
});
if (!isCurrent) {
var isPeriodLocked = ($(this).attr('plock') === 'true');
if (isPeriodLocked) {
menuElement.menu({ disabled: false });
} else {
var isUmltLocked = ($(this).attr('rev') === 'true');
menuElement.menu({ disabled: !isUmltLocked });
}
} else {
//The current period is always unlocked
menuElement.menu({ disabled: true });
}
});
I prepared the demo for you which demonstrates how Split Button can be used inside of jqGrid. It displays
More detailed explanation of the demo I'll post later. Probably you will understand all yourself after examining of the code.

jquery ui autocomplete with autoselect plugin

I am using a jquery ui autocomplete. when the user types in their own value, rather than selecting an item from the list, the textbox clears. This is ok (I don't want the user to be able to enter their own values) except if the user types in a value that does exist on the list.
I tried using the autoSelect plugin as detailed in this post, but it is not working - I added the plugin but when I type in a value that IS on the list and hit tab, I get the same results as before - the textbox clears.
Here is my autocomplete:
$(function () {
$('[id$="txtDocType').autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/MyPage.aspx/myFunction",
data: "{'prefixText':'" + request.term.toLowerCase() + "', 'ddvId':'" + this.element.data('autocomplete') + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) { }
});
},
minlength: 1,
select: function (event, ui) {
$('#divOtherFields input[type=text], input[type=password]').prop("disabled", false).removeClass("disabled");
$('[id$="btnSaveNext"],[id$="btnSaveClose"]').prop("disabled", false);
$('[id$="txtReceiptDate"]').datepicker("setDate", new Date());
}
});
});
Here is the plugin:
(function( $ ) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$( ".ui-autocomplete-input" ).on( "blur", function( event ) {
var autocomplete = $( this ).data( "autocomplete" );
if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" );
autocomplete.widget().children( ".ui-menu-item" ).each(function() {
var item = $( this ).data( "item.autocomplete" );
if ( matcher.test( item.label || item.value || item ) ) {
autocomplete.selectedItem = item;
return false;
}
});
if ( autocomplete.selectedItem ) {
autocomplete._trigger( "select", event, { item: autocomplete.selectedItem } );
}
});
}( jQuery ));
I set a breakpoint in the plugin on this line - "$( ".ui-autocomplete-input" ).on( "blur", function( event )" and the breakpoint was hit, yet the code would not step through. When I set a breakpoint to this line - "var autocomplete = $( this ).data( "autocomplete" );" the breakpoint was NOT hit.
Any ideas? I am at my wits end with this.
I solved this by making a couple of tweaks to the autoSelect plugin. Here is the code that eventually worked for me:
$(".ui-autocomplete-input").bind("focusout", function (event) {
var autocomplete = $(this).data("ui-autocomplete");
if (!autocomplete.options.autoSelect || autocomplete.selectedItem) { return; }
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i");
autocomplete.widget().children(".ui-menu-item").each(function () {
var item = $(this).data("ui-autocomplete-item");
if (matcher.test(item.label || item.value || item)) {
autocomplete.selectedItem = item;
return false;
}
});
if (autocomplete.selectedItem) {
autocomplete._trigger("select", event, { item: autocomplete.selectedItem });
}
});
I used the focus event to set the first value to a hidden variable. The same hidden variable also got updated in the select event. And then this was the hidden variable which I posted to the ajax call.
Why I did not use focus to set the value in the autocomplete input box, was because doing so populated the autocomplete input box even while I was typing in this box.
focus: function (event, ui) {
if($("#streetid")) $("#streetid").val(ui.item.label); //this was my hidden variable
}
},

jquery autocomplete renderItem

I have the following code. It generates no js errors. Can't get the autocomplete to display any results:
$(function() {
$.ajax({
url: "data.xml",
dataType: "xml",
cache: false,
success: function (xmlResponse) {
var data_results = $("Entry", xmlResponse).map(function () {
return {
var1: $.trim($("Partno", this).text()),
var2: $.trim($("Description", this).text()),
var3: $.trim($("SapCode", this).text()),
var4: $("Title", this).text(),
var5: $.trim($("File", this).text()),
var6: $.trim($("ItemID", this).text())
};
}).get();
$("#searchresults").autocomplete({
source: data_results,
minLength: 3,
select: function (event, ui) {
...
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" ).data("item.autocomplete", item)
.append( "<a>" + item.var1 + "<br>" + item.var2 + "</a>")
.appendTo( ul );
};
}
});
Any ideas what I might be missing? Thanks in advance.
It seems that .data('autocomplete') is now .data('ui-autocomplete').
Source: http://jqueryui.com/upgrade-guide/1.10/#removed-data-fallbacks-for-widget-names
By default, autocomplete expects your source array to contain objects with either a label property, a value property, or both.
With that in mind you have two options:
Add a label or value property to your source objects when you process the array from your AJAX call:
var data_results = $("Entry", xmlResponse).map(function () {
return {
var1: $.trim($("Partno", this).text()),
var2: $.trim($("Description", this).text()),
var3: $.trim($("SapCode", this).text()),
var4: $("Title", this).text(),
var5: $.trim($("File", this).text()),
var6: $.trim($("ItemID", this).text()),
value: $.trim($("Description", this).text())
};
}).get();
The value you assign will be used on focus, select, and to search on.
Change the source function to perform custom filtering logic:
$("#searchresults").autocomplete({
source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(data, function (value) {
return matcher.test(value.var1) ||
matcher.test(value.var2);
/* etc., continue with whatever parts of the object you want */
}));
},
minLength: 3,
select: function (event, ui) {
event.preventDefault();
this.value = ui.var1 + ui.var2;
},
focus: function (event, ui) {
event.preventDefault();
this.value = ui.var1 + ui.var2;
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" ).data("item.autocomplete", item)
.append( "<a>" + item.var1 + "<br>" + item.var2 + "</a>")
.appendTo( ul );
};
Note that with this strategy you have to implement custom select and focus logic.

$.ajax({url:link}) and Jquery UI Droppable

I have a problem.
I drop element into #projectsActive. New element have been created there. Old element have been deleted with fadeOut
But ajax query sometimes isn't running.
What's the reason?
$("#projectsActive").droppable({
drop: function (event, elem)
{
var e = elem.draggable;
var linkToSend = "/Projects/Publish/" + $(e).attr("projectid");
$.ajax({ url: linkToSend });
var projectid = $(e).attr("projectid");
var innerText = "";
if ($(e).find("a").length > 0)
{
innerText = $(e).children("a").html();
}
else
{
innerText = $(e).html();
}
var newObject = '<li class="project dragg" projectid="' + projectid + '">' + innerText + '</li>';
$(e).fadeOut("fast", function ()
{
$("#projectsActive").append(newObject);
$(this).remove();
BindDrags();
});
}
});

Resources