I have a table where I make drag and drop. To be possible to make drag and drop and also scroll the page without drag and drop I apply the Jquery Touch.
The problem is when I make a tab in table it shows an error in console.
This is the error
jquery.js:4737 Uncaught TypeError: ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply is not a function
at HTMLTableElement.dispatch (jquery.js:4737)
at triggerCustomEvent (jquery.mobile-events.js:846)
at HTMLTableElement.tapFunc2 (jquery.mobile-events.js:498)
at HTMLTableElement.dispatch (jquery.js:4737)
at HTMLTableElement.elemData.handle (jquery.js:4549)
The code is this:
$('.touchtable').tap('tap', function(e) {
console.log('hola2');
});
How can I fix the error?
The info I read about jquery-touch is here
https://github.com/benmajor/jQuery-Touch-Events
Code to drag and drop
if ($('.touchtable').on('doubletap',function(e){
$("#tbodyproject").sortable({
items: "> tr",
appendTo: "parent",
helper: "clone",
placeholder: "placeholder-style",
containment: ".table",
start: function(event, ui) {
var cantidad_real = $('.table thead tr th:visible').length;
var cantidad_actual = $(this).find('.placeholder-style td').length;
if(cantidad_actual > cantidad_real){
var cantidad_a_ocultar = (cantidad_actual - cantidad_real);
for(var i = 0; i <= cantidad_a_ocultar; i++){
$(this).find('.placeholder-style td:nth-child('+ i +')').addClass('hidden-td');
}
}
ui.helper.css('display', 'table')
},
stop: function(event, ui) {
ui.item.css('display', '')
},
update: function( event, ui ) {
let newOrder = $(this).sortable('toArray');
$.ajax({
type: "POST",
url:'/admin/projects/updateOrder',
data: {ids: newOrder}
})
.done(function( msg ) {
location.reload();
});
}
}).disableSelection();
}));
Code must be like this:
$('.touchtable').on('doubletap', function(e) {
console.log('User tapped touchtable');
});
You should use on method instead tap method and pass the tap parameter on the on method which would call you the tap method.
$('.touchtable').on('tap', function(e) {
console.log('hola2');
});
In another way, you can directly call the tap method like this:
$('.touchtable').tap(function(e) {
console.log('hola2');
});
Note: The first method is an event delegation method and the second method is direct method. If you have dynamically inserted elements, then you must use event delegation method to make it work.
Related
I am using jQuery Sortable to allow users to drag and drop elements on the page. When a user drags a div I need to get the updated order of the list and pass it to the back end. So far I've tried:
$( function() {
$( "#sortable" ).sortable({
axis: 'y',
stop: function (event, ui) {
var data = $(this).sortable('serialize');
alert(data);
$.ajax({
data: oData,
type: 'POST',
url: '/url/here'
});
}
});
$( "#sortable" ).disableSelection();
} );
but this makes the animation really not smooth and alerts no data. How do I get a position list every time a user drags and drops a div?
JSFIDDLE
There's a refreshPositions() function you can use that returns a object representing the sortable item. You can then obtain the updated list of children by making a call to .children() on that object.
Save the positions to a variable in the stop event, which is triggered after you have finished sorting.
I've updated your function to include the stop event:
$("#sortable").sortable({
stop: function(ev, ui) {
//Get the updated positions by calling refreshPositions and then .children on the resulting object.
var children = $('#sortable').sortable('refreshPositions').children();
console.log('Positions: ');
//Loopp through each item in the children array and print out the text.
$.each(children, function() {
console.log($(this).text().trim());
});
}
});
Updated Fiddle
Instead, use the toArray() method, detailed here: http://api.jqueryui.com/sortable/#method-toArray
i have a draggable list, a sortable-droppable list and a couple of li's inside the first.
now i want to pull them over, in the stop-funtion i have a function that adds a class to the first child (it's a span representing the clip-number like
<li>
<span>1.</span>
<span>Title</span>
<span>1min23sec</span>
</li>
). the reason for this is, i want to represent the original clip number in the playlist(sortable).
but i get a console error saying
TypeError: ui.children is not a function
ui.children("li")[0].addClass(".slot_clip_info");
i am not 100% sure, but i think this exact code HAS already worked in the past time, i might have changed somthing without knowing, but i am not aware of that.
draggable:
$(function() {
$(".pl_clipEntry").draggable({
appendTo: "body",
revert: "invalid",
connectToSortable: "#tracks",
distance: 20,
helper: function(){
return $(this).clone().width($(this).width()); // hack for the drag-clone to keep the correct width
},
stop: function(ui) {
ui.children("li")[0].addClass(".slot_clip_info");
},
zIndex: 100
});
});
sortable:
$(function() {
var removeItem;
$("#tracks").sortable({
items: "li:not(.placeholder)",
connectWith: "li",
placeholder: "sort_placeholder",
helper: "clone",
distance: 20,
sort: function () {
$(this).removeClass("ui-state-default");
updatePlaylist();
},
over: function (event,ui) {
updatePlaylist();
removeItem = false;
console.log(event);
console.log(ui);
var originalClass = ui.helper.context.childNodes[0].className;
console.log(originalClass);
var small_clip = originalClass.match(/(\d+)/g)[1];
ui.item.context.children[0].innerHTML = small_clip;
ui.item.context.children[0].classList.add("slot_clip_info");
},
out: function () {
updatePlaylist();
removeItem = true;
},
beforeStop: function(event,ui) {
if (removeItem) {
ui.item.remove();
}
},
stop: function(event,ui) {
console.log("checking placeholder");
var list = $(this);
var count = list.children(':not(.placeholder)').length;
list.children('.placeholder').css("display", count > 0 ? "none" : "block");
savePlaylist();
}
});
as soon as i pull and element IN or reorder them, i get the said error.
also, on refresh, the list seems to multiply itself.. but i guess that's another issue...
Full fiddle (pretty messy, functionality in top dropdown button "PL TOGGLE"
UPDATE: another thing i noticed: the first drag works without problems, then shows the error on release, subsequent drags will (mostly.. sometimes they do...) not work
you need to make ui a jquery object, and then wrap the first element in another jquery object to do what you want.
so change:
ui.children("li")[0].addClass(".slot_clip_info");
to
$($(ui).children("li")[0]).addClass(".slot_clip_info");
In jQuery UI's draggable module, the stop function has 2 parameters : event and ui.
ui is a javascript object (and not a jQuery one, there's a difference.)
This object has 3 attributes :
helper which is a jQuery object
position which is a javascript object
offset which is a javascript object
Depending on your HTML code (we don't have), you could replace
ui.children("li")[0].addClass(".slot_clip_info");
by
ui.helper.children("li")[0].addClass(".slot_clip_info");
I'm using selectable() from jQuery it works just the way i want it.
But i want to go to the next step, i want it to select the message too inside the main chat.
So the text of the selected nickname will highlight too in the main chat.
JsFiddle http://jsfiddle.net/56SkH/13/
UPDATE
What i wanna to do is that when Nickname is selected from users that the channelmessage automaticly is being selected from the users.
$(function() {
$('#users').selectable({
selected: function(event, ui) {
var user = ui.selected.id.toLowerCase();
$('.channelmessage.'+user).addClass('ui-selected');
},
unselected: function(event, ui) {
$('.channelmessage').removeClass('ui-selected');
},
});
});
DEMO: http://jsfiddle.net/56SkH/23/
Try this - On click of each name corresponding message also selected using 'stop' property of selectable().
$(function () {
$("#users").selectable({
stop: function () {
$("#users li").each(function (key) {
$("#Nickname" +(key+1)+ "_message").css({"background":"white","color":"black"});
});
$(".ui-selected", this).each(function (key) {
var index = $( "#users li" ).index( this );
$("#Nickname" +(index + 1)+ "_message").css({"background":"#F39814","color":"white"});
});
}
});
});
It's easy to add a dummy class to each chat message, and the selector will be more efficient than searching for a name string.
$(function() {
$( '#users').selectable({
filter: "li",
selecting: function( event, ui ) {
$(".ui-selected").removeClass("ui-selected");
$('.channelmessage span.message.' + ui.selecting.id).addClass("ui-selected");
}
});
});
Here you have a working JSFiddle sample:
http://jsfiddle.net/56SkH/21/
You can force the selection on the element by adding the class ui-selected and using the selected event:
$(function () {
$('#users').selectable({
selected: function (event, ui) {
$(".channelmessage span.nickname.ui-selected").removeClass("ui-selected");
$(".channelmessage span.nickname:contains('" + ui.selected.id + "')").addClass("ui-selected");
}
});
});
In the example I use the span content as contains selctor, by I have modified a bit the HTML markup like:
<p class="channelmessage"> <span class="nickname">Nickname2</span><span>:</span>
<span class="message">Message</span>
</p>
Demo: http://jsfiddle.net/IrvinDominin/LnnLT/
Hi I have the code below for autocomplete which works fine but my only issue is that when a user clicks on an option from the autocomplete list, it should trigger another function (doSomething()). This however is not being done. Granted if the user makes a selection and presses "enter" the function is executed.
var url = "http://myURL";
var field = "myField";
$(document).ready(function () {
$("#tags").autocomplete({
source: function (req, add) {
var suggestions = search(req.term, url, field);
add(suggestions);
},
select: function( event, ui ) {
doSomething();
}
});
});
function search(value, listurl, field) {
var coll = new Array();
var url =
listurl + "?$filter=startswith(" + field + ",'" + value + "')";
$.ajax({
cache: true,
type: "GET",
async: false,
dataType: "json",
url: url,
success: function (data) {
var results = data.d.results;
for (att in results) {
var object = results[att];
for (attt in object) {
if (attt == field) {
coll.push(object[attt]);
}
}
}
}
});
return coll;}
function doSomething() {
}
Thanks for any suggestions.
Got this resolved like this:
$('#tags').on('keyup change', function () {
doSomething();
}).change();
$('#tags').on('autocompleteselect', function (e, ui) {
doSomething();
});
Thanks to this SO link
I know this is an old topic, but I came across this problem and I found another solution which I believe JQuery provides for. You can use the close event to do this.
Examples (extracted from http://api.jqueryui.com/autocomplete/ and adapted for this question):
1) When you initialize the autocomplete
$( "#tags" ).autocomplete({
close: function( event, ui ) { doSomething(); }
});
or
2) Binding an listener to the close event
$( "#tags" ).on( "autocompleteclose", function( event, ui ) { doSomething(); } );
I will simplify my explanation so you get what I am doing. I have two div's and I set up portlets as shown here, however I am dynamically injecting my portlets, no big problem there.
<div id="mainallapplicant" class="myrow"></div>
<div id="contingent_right" class="myrow"></div>
Here is the JavaScript
$( ".myrow" ).sortable({
connectWith: ".myrow",
revert: true,
beforeStop: function( event, ui ) {}
});
I am trying to allow a maximum of only one droppable into mainallapplicant. If there is one already there, I will show a confirmation dialog and depending on the answer, I cancel the drop or move out the existing item and replace it with the new item. I tried the following but I am getting nowhere.
$( ".myrow" ).sortable({
connectWith: ".myrow",
revert: true,
start: function(event, ui) {
if ($(this).prev().find(".portlet").length == 1) {
ui.sender.draggable("cancel");
}
},
stop: function(event, ui) {
if ($(this).prev().find(".portlet").length == 1) {
ui.item.remove();
// Show an error...
}
}
});
You can use start to get the current count of portlet elements, then use stop to do the checking
Also notice I added class names to each div to allow only one div to have a maximum of 1 portlet
$(document).ready(function () {
$.count = 0;
$(".myrow").sortable({
connectWith: ".myrow",
revert: true,
start: function () {
$.count = $(".myrow").has(".portlet").length;
console.log("Start " + $.count);
},
stop: function (event, ui) {
if ($(ui.item).parent(".myrow").hasClass("left")) {
if ($.count == 2) {
$(".myrow").sortable("cancel");
}
}
}
});
});
DEMO: http://jsfiddle.net/Ue4dq/