The calendar lets the user drag a timeslot onto the calendar, however I would like them to be able to remove it if they click on it.
So in the eventClick I have this function:
function (calEvent) {
removeRequestedEvent($(this), calEvent);
},
It just passes in the calendar event and the calendar itself.
removeRequestedBooking: function (cal, calEvent) {
if (!confirm("Delete?"))
return;
cal.fullCalendar("removeEvents", calEvent.id);
cal.fullCalendar("rerenderEvents");
// Re-show draggable element
$("#requests #" + calEvent.id).show();
}
I've also tried using a filter, but a breakpoint on the return statement is never hit.
cal.fullCalendar("removeEvents", function (event) {
return event.id == calEvent.Id;
});
Any ideas? (I know the Id is right, and the last line works). Firebug doesn't show any errors in the javascript.
I'm using FullCalendar v1.4.10
When you have all your id's in place use Tuan's solution.
But when you do NOT have id's in your event do it like this (this work also when you have id's set):
eventClick: function(event){
$('#myCalendar').fullCalendar('removeEvents',event._id);
}
Why this problem appear?
The common reason for that is fullcalendar doesn't add id automatically when you're adding new event. If so, id which you have passed is undefined. Fullcalendar uses id in both cases when you're trying delete using id or filter. So when it's value is undefined it always return false. Meaning list of elements to delete is always empty.
Even simpler:
eventClick: function(calEvent, jsEvent, view) {
$('#calendar').fullCalendar('removeEvents', function (event) {
return event == calEvent;
});
}
Instead of using your passed in cal, can you try using a call to the div that holds your calendar?
In the case of eventClick, this refers to the HTML for the event according to what I'm reading in the docs.
Use refetchEvents:
cal.fullCalendar("refetchEvents");
Justkt's answer took me a second to wrap my head around, but I'll post my results for any other noobs who need to see the code in a really simple way:
eventClick: function(event){
var event_id = event.id;
$.post('/Dropbox/finance/index.php/welcome/update', {"event_id": event_id},
function(data){
$('#calendar').fullCalendar("removeEvents", (data));
$('#calendar').fullCalendar("rerenderEvents");
}
});
}
The PHP (using codeignighter):
public function update(){
$result = $this->input->post('event_id');
echo $result;
// would send result to the model for removal from DB, or whatever
}
I use filter function with event.start and it works well
calendar.fullCalendar('removeEvents', function(event) {
return
$.fullCalendar.formatDate(event.start, 'yyyyMMdd')
== $.fullCalendar.formatDate(start, 'yyyyMMdd');
});
Related
I have a table with a row defined like this:
<tr>
<td id="to-watch">
#Model.Results.Seats
</td>
</tr>
Edit: The table values are being updated by ajax calls to an action which is returning data to the table in a partial
I want to log to the console when the value is greater than 2, here is the jQuery code I have:
$('#to-watch')
.change(function () {
if ($('#to-watch').val() > 2) {
console.log("************ WINNER ***************");
}
});
I have checked in Chrome debugging tools nothing is being logged to the console when the value is greater than 2 - I rarely use jQuery / JavaScript, and after some looking, haven't been able to find the answer..
Edit: I'm making the ajax call like this:
$(document).ready(function () {
(function loop(i) {
setTimeout(function () {
callAjax(i);
//console.log("works " + i);
},
500); // ms
function callAjax(i) {
$.ajax({
url: '/Home/StartElection',
type: 'POST',
data: "test",
async: true
})
.done(function (partialViewResult) {
$("#partialTable").html(partialViewResult);
}).always(function () {
if (--i) loop(i);
});
};
})(650);
});
There are a couple of problems here.
Firstly, the change event is for input fields. It will execute the callback whenever the value of the input field changes.
There is an equivalent for when any html changes, using Mutation Observers, but it's overly complex for this scenario, as you know when the html changes, and it is done via your code.
Secondly, you are attaching an event listener to #to-watch, which I assume is nested inside #partialTable. Now we already know the change event won't work anyway, but even if this was an input field, we would have the following problem:
Attach listener to DOM element with #to-watch
Make ajax call
On return of ajax call, replace all of #partialTable with a new version of it.
The old #to-watch element is now gone, and so is it's event listener. It can't be triggered anymore.
The solution to this is called event delegation. Meaning you attach the listener to a parent element that doesn't change, and it checks if any child elements matching the selector are changed. This means that id the child elements were changed dynamically, the listener will still work.
Then there are also the aforementioned:
$('...').text() will give you the contents of any DOM element, where as $('...').val() will give the value of an input field
JQUERY .text() docs
JQUERY .val() docs
You want to do a numerical comparison (X > Y), so you should convert the string "2" which is the text of $('#to-watch') into an integer with parseInt(x)
The solution to your problem
When you update the #partialTable, you know that the #to-watch element has received a new value, so now is the time to check it:
function callAjax(i) {
$.ajax({
url: '/Home/StartElection',
type: 'POST',
data: "test",
async: true
}).done(function (partialViewResult) {
$("#partialTable").html(partialViewResult);
if (parseInt($('#to-watch').text()) > 2) {
console.log("************ WINNER ***************");
}
}).always(function () {
if (--i) loop(i);
});
};
Instead of val() can you please try text() in the JQuery function.
Please try text() .
text() - Sets or returns the text content of selected elements
html() - Sets or returns the content of selected elements (including HTML markup)
val() - Sets or returns the value of form fields
Please check the this link for DOM Insertion using Jquery
$(body).on('mycontentchange','#to-watch', function() {//make sure #to-watch is available in DOM while binding, or use `on` to delegate the event
console.log('new content updated',$('#to-watch').text());
});
.done(function (partialViewResult) {
$("#partialTable").html(partialViewResult);
$('#to-watch').trigger('mycontentchange');
}).always(function () {
if (--i) loop(i);
});
This is just a direct answer to the question, you probably have better ways to solve the problem :) This is an overkill as #jeremy pointed out considering your continuous polling.
I am wondering why i have to do this:
$($("body").children("div")[0]).modal('show');
instead of
$("body").children("div")[0].modal('show');
Doesn't the function .children give back a list with nodes? I am new to jquery and not that experienced yet with javascript so i was just wondering what the difference is.
.modal is a bootstrap function in case anyone was wondering.
Here is the context for completeness:
'click .edit': function (e, value, row, index) {
$.ajax({
url: "index.php?controller=" + controller + "&action=edit&id=" + row['id'] + "&type=modal",
success: function (result) {
if (result !== null) {
$("body").prepend(result);
$($("body").children("div")[0]).modal('show');
} else {
alert("There was a problem with editing. Please contact a system admin or try again.");
}
}
});
e.stopPropagation();
},
Because ("div")[0] will return a dom element., which doesnt have jquery functions associated in it. Inorder to associate jquery functions to that element, you need to convert it again to jquery element by warping the $()
Other option is to use eq() operator like this,
$("body").children("div:eq(0)").modal('show');
The returned element is a javascript DOM element which is not wrapped by any jQuery function. Hence you have to wrap it with another $ mark. If you want to get the first element, use $("body").children("div").first() this will get you the first element as a jQuery object where you can use all the jQuery function.
I have two types of events in my fullCalendar. Few are the fetched from the eventSources using :
$('calendar').fullCalendar('addEventSource' , 'source')
And few are created by the user. I am using
$('calendar').fullCalendar('renderEvent', eventData, true)
Now upon clicking a button I want to remove all the events that are obtained from the eventSources and retain those that are created by the user.
I tried doing :
$('calendar').fullCalendar('removeEventSource' , function(e){ return true ; } ) ;
But that doesn't work. How do I achieve doing the job ?
You can simply call:
$('#calendar').fullCalendar('removeEventSources');
I did exactly what you want to do in a recent project.
Fullcalendar supports nonstandard fields.
Non-standard Fields
In addition to the fields above, you may also include your own
non-standard fields in each Event Object. FullCalendar will not modify
or delete these fields. For example, developers often include a
description field for use in callbacks such as eventRender.
Source
So you could do something like
//Save user created event
$('#calendar').fullCalendar('renderEvent', {
title: title,
end: end,
start: start,
editable : true,
//nonstandard field
isUserCreated: true,
description: description,
});
then to remove events that hasn't been created by user
//Get all client events
var allEvents = $('#calendar').fullCalendar('clientEvents');
var userEventIds= [];
//Find ever non usercreated event and push the id to an array
$.each(allEvents,function(index, value){
if(value.isUserCreated !== true){
userEventIds.push(value._id);
}
});
//Remove events with ids of non usercreated events
$('#calendar').fullCalendar( 'removeEvents', userEventIds);
or if you need less control then simply (as #A1rPun suggested)
$('#calendar').fullCalendar( 'removeEvents', function(e){ return !e.isUserCreated});
They added ways to remove both event sources and events in event calendar, as long as you're using 2.8.0.
To remove all event sources or all events from full calendar, do the following:
$('#calendar').fullCalendar( 'removeEventSources', optionalSourcesArray)
If optionalSourcesArray isn't defined, it simply removes all event sources. In my case, I needed to remove event sources, so I called:
$('#calendar').fullCalendar( ‘removeEvents’, idOrFilter )
See the documentation for both method calls here:
https://fullcalendar.io/docs/removeEventSources
https://fullcalendar.io/docs/removeEvents
You can read more about the original removeEventSources pull request and how it's actually implemented here:
https://github.com/fullcalendar/fullcalendar/issues/948
The first click event sends an API call that returns several search results.
The second click event should occur when clicks 'upvote', which is an option in each returned search result.
Problem is, it seems that I can't select upvote buttons in search results because they were created (via cloning another element) after the first click event.
Can anyone explain why this happens?
Part of the first click event:
success: function(json) {
var reviews = json.reviews;
$.each(reviews, function(i) {
var critic = reviews[i].critic;
var quote = reviews[i].quote;
var score = reviews[i].original_score;
$('#tile-demo').clone().removeAttr('id').removeClass('hidden')
.find('.critic-name').text(critic).end()
.find('.critic-score').text(score).end()
.find('.critic-quote').text(quote).end()
.appendTo('.review-grid');
}); //end each loop
} //end success call
the new call, which should select a clone of #tile-demo:
$('.search-results').click(function(){
var goodCritic = $(this).siblings('.critic-name').text();
console.log(goodCritic);
});
Use On method as the following:
$('#containerId').on('click','upvotebuttons',function(){write your code here});
where containerId is the id of the container div where you render new data, and replace [upvotebuttons] with [class name] of the upvote buttons.
I just came across a quick screencast by Jeffrey Way that suggests a slightly different solution. The other answer works fine--this is just another way to go about it (still uses event delegation).
$('#parent-of-target').click(function(e) {
if ( $(e.target).is('#target-element') ) {
alert('clicked');
}
});
i have a list of dynamically created check boxes. when the state of the check box changes, a function is executed. the function runs perfectly in firefox 3.6 perfectly whether the user clicks the check box, or uses keyboard input to change the check box. in chrome or safari, the function executes fine using the keyboard, but errors out with a mouse click. i cannot seem to find why the code acts differently from a mouse click vs a keyboard entry.
here is what i believe is the pertinent code:
var q_id = $j('label:contains("SCORP Statewide Need ")').attr('for');
console.log(q_id); //writes out answer id a_721
an ajax post will create a list of check boxes:
if(found == true){
output+="<div name='"+q_id+"'><input type='checkbox' name='"+q_id+"' id='"+q_id+"."+i+"' class='check' checked='checked' onChange='saveStateNeed("+q_id+")' value='"+list[i]+"'/>";
}else{
output+="<div name='"+q_id+"'><input type='checkbox' name='"+q_id+"' id='"+q_id+"."+i+"' class='check' onChange='saveStateNeed("+q_id+")' value='"+list[i]+"'/>";
}
output+=" <label name='l_"+q_id+"' for='"+q_id+"."+i+"' id='l_"+q_id+"."+i+"'>"+ list[i] +"</label></div>";
output+="<div class='clearboth'></div><br/>";
$j('##div_'+q_id).append(output);
all this is generated perfectly in all browsers.
the error is in the callback saveStateNeed();
function saveStateNeed(list){
console.log('in saveStateNeed');
console.log(list);// prints out an array of the checkboxes [input#a_721.0.check Non-motorized trails, input#a_721.1.check Sports a...ayfields, input#a_721.2.check Land Acq...projects, input#a_721.3.check Picnicki...cilities, input#a_721.4.check Nature s...wildlife]
// **in safari i get function()** but it still works with keyboard, fails with click
// the next assignment $me fails.
var $me = $j('input [name="'+list+'"]');
var isChecked = $me.context.activeElement.checked;
var $value = $me.context.activeElement.attributes['value'].nodeValue;
console.log($me); out puts the object selected as an expandable firebug object []
console.log($value); outputs label for object: Picnicking/day use facilities
console.log(isChecked); outputs true false
if(isChecked){
}else{
}
$j.ajax({
type: "POST",
url: });
}
this is all kind of convoluted, im just hoping someone knows why i would get a different result from a click then a keyboard entry, when the same code is actually being executed.
i really hope this isnt all too convoluted.
thanks for taking a look at this, and i really appreciate any comments or suggestions you might have.
cheers.
You might have better luck if you attach the checkbox behavior as a delegated event instead of explicit assignment.
It looks like you're using jQuery, so you can do that like so:
$j('input.check').live('change', function(event) {
var jThis = $j(this);
// grab id from checkbox
var ID = jThis.attr('id').split('.')[0];
saveStateNeed(ID, jThis.attr('checked'));
return true;
});
Also: are you certain that the error is in the event handler, and not in the saveStateNeed function?
EDIT: Based on your updates, here's what I've got. First, note the minor change to the function above; now it passes two values. Second, if you want to act on a checkbox being toggled, modify saveStateNeed to accept two values: an ID and a boolean. Like so:
function saveStateNeed(ID, bChecked) {
console.log('checkbox ' + ID + ' is ' + (bChecked) ? 'checked' : 'not checked');
if(bChecked) {
// do something
} else {
// do something else
}
}