fullcalendar events drag and drop not working in firefox - javascript

The drag and drop works fine on other browsers just firefox that has an issue.
I have read enough to know that Firefox has a different mechanism for drag and drop but nothing I found has helped
Tried implementing jsEvent.preventDefault(); as the commentor suggest here
but that did not change the behavior and Im not sure how to implement the marked as answer portion which does event.originalEvent.dataTransfer.setData('text/plain', 'anything');
Here is my drag and drop code:
setup draggable tr
$('#workOrdersTable tbody tr').each(function() {
var tds = $(this).children('td');
if (tds.length > 0) {
var workOrder = $.grep(workOrders, function(e) {
return e.woNumber == tds[0].innerText;
})[0];
if (typeof workOrder !== "undefined" || workOrder !== null) { // store the Event Object in the DOM element so we can get to it later
$(this).data('workOrder', workOrder);
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
}
}
});
How can I get this working in Firefox?
FullCalendar setup implementing drop
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: false,
droppable: true,
//edit existing
eventClick: function(calEvent, jsEvent, view) {
populateEvent(calEvent, true);
},
//create new
drop: function(date, jsEvent, ui ) {
//alert('jsEvent '+jsEvent);
jsEvent.preventDefault();
var workOrder = $(this).data('workOrder');
workOrder.title = workOrder.woNumber + ' ' + workOrder.account
workOrder.description = workOrder.problemDescription;
workOrder.start = date;
workOrder.end = moment(date).add(1, 'hour'); //change default so the start and end dont match
populateEvent(workOrder, false);
},

The issue was with setting the data onto the draggable row
var workOrder = $.grep(workOrders, function(e) {
return e.woNumber == tds[0].innerText;
})[0];
needed to be
var woNumberTemp = tds[0].textContent || tds[0].innerText;
var workOrder = $.grep(workOrders, function(e) {
return e.woNumber == woNumberTemp;
})[0];
Appearently for chrome tds[0].innerText is fine but firefox needs tds[0].textContent

Related

Jquery - appending after re-registering

On this script I have drag and drop fieldsets (left menu - top). Drag multiple fieldsets into the right "working area". In those fieldsets is an area for dropping Fields (of which I have one, left menu - bottom). Drop "Field One" into any of the dropped Fieldset (under the line in the "Drop Fields Here" area) in the working area.
I want to then move that Field One from the Fieldset I dropped it into and into the other Fieldset in the working area. I have got the Field One draggable but I cannot get it to append to the new Fieldset.
I am not wanting to delete the Field and replace it with another clone from the left menu. I am new to jquery so my code may be a bit messy. Any help is greatly appreciated. Jsfiddle and code below.
I believe the code issue is between line 21-29...but I am not sure.
JsFiddle Link
$(document).ready(function() {
var fs_count = 0;
$("#drop-area").droppable({
accept: '.ui-draggable:not(.draggableField , .activeField)',
drop: function(event, ui) {
fs_count++;
var clone = $(ui.draggable).clone()
clone.addClass('.connectedSortable')
// clone.removeClass('.ui-draggable');
if (clone.hasClass('dropped')) {
return false;
}
clone.addClass('.connectedSortable').addClass('dropped').attr('id', 'fs_' + fs_count);
$(this).append(clone);
var fs_class = clone.attr('class');
alert('You added a field with class ' + fs_class);
var fieldsDroppable = $('#drop-area .ui-draggable:last-child .fieldDroppable');
fieldsDroppable.droppable({
accept: '.draggableField , .activeField',
drop: function(event, ui) {
var clone = $(ui.draggable).clone();
if (clone.hasClass('draggableField')) { // If else to prevent clones reproducing in Fieldsets when moving from original Fieldset.
clone.removeClass('ui-draggable , draggableField').addClass('activeField');
$(this).append(clone);
}
else {
// Append the div here?
}
var cloneClass = clone.attr('class'); // Temporary varialble for develpoment alert below
alert('you dropped a field' + cloneClass); // Temporary for development only
// Below re-register the "field" with jquery....not sure this is entirely correct.
var fieldsDraggable = $('#drop-area .ui-draggable .fieldDroppable .activeField');
fieldsDraggable.draggable();
}});
} });
$(".fieldDroppable").droppable({
accept: '.draggableField , .activeField',
drop: function(event, ui) {
var clone = $(ui.draggable).clone()
$(this).append(clone);
}
});
$(".ui-draggable").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid'
});
$(".draggableField").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'false'
});
$(".activeField").draggable();
$("#drop-area").sortable({
handle: '.drag-handle',
update: function () { //triggered when sorting stopped
var dataAuto = $("#drop-area").sortable("serialize", {
key: "za",
attribute: "id",
});
alert(dataAuto);
}
});
$("#drop-area").disableSelection();
});
There will be a lot of work to do here, yet you can get over this hurdle like so:
https://jsfiddle.net/Twisty/6trmrfoo/32/
Basically, you want to assign a new .droppable() to a specific element in the field set when it is added to the #drop-area. I would advise using a function as you will do this a multitude of times.
You can also make use of .data() to store a source value along with the draggable elements. I only did this for fields since that was the only pace it seemed like it was needed. You can updated this once it's dropped into a fieldset so that future drag-n-drop operations can be handled properly, we don't want to clone the object we move it.
To move it, consider using .detach(). It'll detach the element from the current parent and can be used in chain to append or move into memory as a variable. Similar to .clone() just we're manipulating the actual object. .clone() is to "Copy & Paste" as .detach() is to "Cut & Paste".
JavaScript
$(function() {
var fs_count = 0;
function makeFieldTarget($fs) {
$fs.droppable({
accept: '.draggableField, .activeField',
drop: function(event, ui) {
var clone, cloneClass;
if (ui.draggable.data("source") == "sidebar") {
clone = $(ui.draggable).clone();
clone.removeClass('draggableField').addClass('activeField');
$(this).append(clone);
cloneClass = clone.attr('class');
console.log('DROPFIELD - you dropped a field from the side bar: ' + cloneClass);
clone.data("source", "fieldset").draggable({
zIndex: 1000
});
}
if (ui.draggable.data("source") == "fieldset") {
clone = ui.draggable;
clone.detach().attr("style", "").appendTo($(this));
cloneClass = clone.attr('class');
console.log('DROPFIELD - you dropped a field from a Field set: ' + cloneClass);
}
}
});
}
$("#drop-area").droppable({
accept: '.ui-draggable:not(.draggableField, .activeField)',
drop: function(event, ui) {
fs_count++;
var clone = $(ui.draggable).clone()
clone.addClass('connectedSortable');
if (clone.hasClass('dropped')) {
return false;
}
clone.addClass('connectedSortable dropped').attr('id', 'fs_' + fs_count);
$(this).append(clone);
var fs_class = clone.attr('class');
console.log('DROPAREA - You added a field with class ' + fs_class);
makeFieldTarget(clone.find(".fieldDroppable"));
$("#drop-area").sortable("refresh");
}
});
$(".ui-draggable").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid'
});
$(".draggableField").data("source", "sidebar").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'false',
zIndex: 1000
});
$("#drop-area").sortable({
handle: '.drag-handle',
placeholder: "drop-place-holder",
items: ">div.dropped",
update: function() { //triggered when sorting stopped
var dataAuto = $("#drop-area").sortable("serialize", {
key: "za",
attribute: "id",
});
alert(dataAuto);
}
});
$("#drop-area").disableSelection();
});

Make draggable sortable with the droppable

I made a drag & drop system. The draggable items can be dropped in placeholders. Those placeholders are added dynamically based on the amount of draggable items.
But when I drag a draggable item between those placeholders, it doesn't get appended to it. I've tried many many things but I'm still stuck on it.
I'm afraid that I'll need to change a lot of the code, but maybe one of you has a genius idea on how to solve this.
Here's the jsfiddle
Is it possible to check wether it has been placed on a placeholder, or not?
This is my droppable function:
function dropping () {
$("li.placeholder").droppable({
accept: ".to-drag",
hoverClass: correct_placeholder,
activeClass: active_placeholder,
revert: false,
tolerance: "pointer",
drop: function (event, ui) {
var dragging = ui.draggable.clone().find("img").remove();
$(this).append(dragging).addClass("dropped");
$(this).droppable('disable');
var day = $(ui.draggable).attr('data-id');
var index = $(event.target).index();
$(this).attr("data-id", day);
$(this).attr("date-order", index);
$(this).addClass("drop-"+ index);
$(this).attr("data-content", "");
$(this).find("h1, p").remove();
var dropped = $(".dropped").length;
var original = $(".placeholder").length;
if (dropped === original) {
$("li.placeholder").removeClass(blank_placeholder);
$("#dropzone").append('<li class="placeholder ' + blank_placeholder +' " data-id="" data-order=""></li>');
init();
}
$(".remove").click(function() {
var removable = $(this).parent();
var modal = $(this).attr("data-modal");
$(".modal-"+modal).remove();
if (dropped > original) {
$(this).parent().droppable('enable')
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
$(this).parent().droppable('enable');
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
init();
});
}
});
$("li.dropped").droppable({
disabled: function (event, ui) {
disabled: true
}
});
}

Is it possible to assign the background colour of a FullCalendar event based on its title?

As FullCalendar isn't able to read the colours that are assigned to events in Google Calendar I need to be able to style the way events are displayed based on the text content of the individual event titles.
Having read as many posts as I can find on the matter, it would seem that FullCalendar's 'eventRender' is the most likely route to take but the closest I can find to what I need is something along the lines of:-
eventRender: function(event, element) {
if(event.description == "blah blah") {
element.css('background-color', '#ff000');
My problem is, (a) I need eventRender to apply to the event titles rather than their descriptions, and (b) I need it to be a case of 'if the title includes the words blah-blah', rather than 'if the title is an exact match for blah blah'.
I hope all the above isn't too garbled and nonsensical. I'm still very much feeling my way with all this; so any help, advice, thoughts, or steers in the right direction would be most gratefully received! :)
Many thanks, in advance, for your time.
Edited:
Additional info. The script that I'm using on the FullCalendar html page (sans API key and Google ID)
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
height: 'auto',
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaDay,month',
},
eventRender: function(event, element) {
if(event.description == "blah blah") {
element.css('background-color', '#ff000');
}
},
// Google API key
googleCalendarApiKey: 'xxxxxxxxx',
// Diary Dates
events: 'xxxxxxxxx',
eventClick: function(event) {
// opens events in a popup window
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
</script>
in the eventRender callback
if(-1 != event.title.indexOf("blah blah")) {
element.find('.fc-title').css('background-color', '#ff000');
}
will do it.
or better yet, apply a style element.addClass("event-bg-class");
Did you basically try ?
if(-1 != event.title.indexOf("blah blah")) {
element.css('background-color', '#ff000');
}
# Hope it'll help you
element.addClass("custom-event-0");
element.addClass("custom-event-1");
$(document).ready(function() {
var eventsdata = [];
var i = 0;
$('#calendar').fullCalendar({
height: 'auto',
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaDay,month',
},
eventRender: function(event, element) {
if(event.description == "blah blah") {
element.css('background-color', '#ff000');
}
},
// Google API key
googleCalendarApiKey: 'xxxxxxxxx',
// Diary Dates
events: 'xxxxxxxxx',
eventRender: function(event, element) {
if(eventsdata.length == 0){
eventsdata.push(event.title);
i++;
}else{
var tmp = eventsdata.indexOf(event.title);
if(tmp == -1){
eventsdata.push(event.title);
i++;
}
}
element.addClass("custom-event-"+eventsdata.indexOf(event.title));
},
eventClick: function(event) {
// opens events in a popup window
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});

Get the event data in manually bind events in full calender

I am using full calendar in that I need to handle both click and dblclick event on eventclick.
For that I did the following code.
Taking data from server and from json data :
function FormJosn(Data) {
var Json = [];
for (var i = 0; i < Data.length; i++) {
Json.push({
"id": Data[i].Appointment_ID,
"title": Data[i].F_Name + ' ' + Data[i].L_Name,
'start': Data[i].start,
'end': Data[i].End,
'allDay': false
});
}
Calander(Json);
}
and render full calender,
function Calander(Data) {
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
editable: true,
droppable: true,
drop: function (date, allDay) { // this function is called when something is dropped
// retrieve the dropped element's stored Event Object
var originalEventObject = $(this).data('eventObject');
// we need to copy it, so that multiple events don't have a reference to the same object
var copiedEventObject = $.extend({}, originalEventObject);
// assign it the date that was reported
copiedEventObject.start = date;
copiedEventObject.allDay = allDay;
// render the event on the calendar
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
select: function (start, end, allDay) {
SetAppointmentBookingDateTime(start);
calendar.fullCalendar('unselect');
},
editable: false,
disableResizing:false,
events: Data,
eventRender: function (event, element)
{
element.bind('click', function (event, element) {
var doubleClickOpportunity = 200, // Adjust this to whatever feels right
$elem = $(event.target),
clicker = $elem.data('clicker'); // Holder for the doubleclick setTimeout
if (clicker) {
// If there's a setTimeout stored in clicker, then this is a double click
clearTimeout(clicker);
$elem.data('clicker', '');
$elem.trigger('doubleclick');
} else {
$elem.data('clicker', setTimeout(function () {
$elem.data('clicker', '');
$elem.trigger('singleclick');
}, doubleClickOpportunity));
}
});
element.bind('singleclick', function (event, element) {
// I'm a single click!
window.location = "http://" + window.location.host + "/Hospital/Treatment/AddTreatment/" + event.id;
});
element.bind('doubleclick', function () {
// I'm a double click!
$(".Modify-Appointment").modal("show");
});
}
});
}
I have bind click and dblclick eventRender which will working fine but I am not getting data of the event as it get it on eventClick function.
I need those data to proceed further.
In order to pass data to jQuery's callback, as per the bind documentation, you should use the following signature:
.bind( eventType [, eventData ], handler )
So you must pass an object to the callback, like this:
element.bind('singleclick', { event: event, element: element }, function () {
// I'm a single click!
window.location = "http://" + window.location.host + "/Hospital/Treatment/AddTreatment/" + event.id;
});
Also note that as of jQuery 1.7, .on() is the preferred method over .bind()

Fullcalendar not working in FF on a windows machine

I have a problem of dragging and dropping external elements to a calendar (Fullcalendar) on a windows machine. All works fine on a linux, mac machine. But does not save to the database on a windows machine. What may be the problem??
jQuery(document).ready(function() {
/* initialize the external events
-----------------------------------------------------------------
*/
jQuery('#external-events div.external-event').each(function() {
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
// it doesn't need to have a start or end
var eventObject = {
title: jQuery.trim(jQuery(this).text()) // use the element's text as the event title
};
// store the Event Object in the DOM element so we can get to it later
jQuery(this).data('eventObject', eventObject);
// make the event draggable using jQuery UI
jQuery(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
// page is now ready, initialize the calendar...
jQuery('#calendar').fullCalendar({
loading: function(bool) {
if (bool) jQuery('#loading').show();
else jQuery('#loading').hide();
},
events: "/roster/manage/ajax?part=shiftcalendar&nodeID="+placeid,
// put your options and callbacks here
header: {
left: 'prev,next today',
center: 'title',
right: 'prev,next today',
},
cache: false,
editable: true,
droppable: true, // this allows things to be dropped onto the calendar !!!
drop: function(date, allDay) { // this function is called when something is dropped
// retrieve the dropped element's stored Event Object
var originalEventObject = jQuery(this).data('eventObject');
// we need to copy it, so that multiple events don't have a reference to the same object
var copiedEventObject = jQuery.extend({}, originalEventObject);
// assign it the date that was reported
copiedEventObject.start = date;
copiedEventObject.allDay = allDay;
// render the event on the calendar
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
jQuery('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
// Call this function to store the date and time of this shift into a table
saveShift(originalEventObject,copiedEventObject);
},
eventDrop: function(event,dayDelta,minuteDelta,allDay,revertFunc) {
if (!confirm("Are you sure you want to change dates?")) {
revertFunc();
}
else {
// Our edit function for this shift
updateShift(event);
}
},
eventClick: function(event,revertFunc) {
if(!confirm("Are you sure you want to delete this "+ event.title +" shift?")) {
revertFunc();
}
else {
// Delete shift
deleteShift(event);
}
}
/*eventMouseover: function(event, jsEvent, view) {
jQuery.getJSON('/roster/manage/ajax', {part: "shiftcalendarpeople", shiftID: event.id }, function(data) {
if(data != null) {
var layer = "<div id='events_"+event.id+"'>";
jQuery.each(data, function(k, v) {
layer += "<span>"+v.user+" as "+v.role+"</span>";
});
layer += "</div>";
jQuery(this).append(layer);
}
else {
var layer = "<div id='events_"+event.id+"'><span>No people rostered.</span></div>";
jQuery(this).append(layer);
}
});
},
eventMouseout: function(event, jsEvent, view) {
jQuery("#events_"+event.id+"").remove();
}*/
})
});
Usually when something works on every machine except windows (or vice-versa) it's because of path issues. I see that you use a unix path in a variable
events: "/roster/manage/ajax?part=shiftcalendar&nodeID="+placeid
Maybe try using the windows style path "\roster\manage\ajax?part=shiftcalendar&nodeID="+placeid
It's a rough guess. It's what jumps to my eyes at first glance.

Categories