I have a controller that gets data from database and turns it in events for fullcalendar, when I display a modal clicking in one of this events, it shows that description and email are undefined.
Image of modal undefined fields
But in XHR I can see that im receiving all the data from the controller.
Image of XHR GET
Modal:
<div id="fullCalModal" class="modal fade" style="z-index: 9999;>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 id="modalTitle" class="modal-title"></h4>
</div>
<div id="modalBody" class="modal-body">
<p id="ev_start" class="modal-body"></p>
<p id="ev_end" class="modal-body"></p>
<p id="ev_mail" class="modal-body"></p>
<p id="ev_desc" class="modal-body"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button class="btn btn-primary"><a id="eventUrl" target="_blank">Event Page</a></button>
</div>
</div>
</div>
Javascript:
eventClick: function(info) {
var eventObj = info.event;
alert('Clicked ' + eventObj.title + ' with id: ' + eventObj.id + eventObj.description);
$('#modalTitle').html(eventObj.title);
$('#ev_titulo').html(eventObj.title);
$('#ev_start').html('Fecha inicio: ' + eventObj.start);
$('#ev_end').html('Fecha fin: ' + eventObj.end);
$('#ev_desc').html('Descripcion: ' + eventObj.description);
$('#ev_mail').html('Mail: ' + eventObj.mail);
$('#fullCalModal').modal('show');
},
Controller:
public function loadAction()
{
$em = $this->getDoctrine()->getManager();
$eventos = $em->getRepository('App:Evento')->findAll();
$data = array();
foreach ($eventos as $evento)
{
$events['id'] = $evento->getId();
$events['title'] = $evento->getTitle();
$events['start'] = $evento->getBeginAt()->format('Y-m-d');;
$events['end'] = $evento->getEndAt()->format('Y-m-d');;
$events['color'] = $evento->getColor();
$events['description'] = $evento->getDescription();
$events['mail'] = $evento->getMail();
array_push($data, $events);
}
return $this->json($data);
}
The event parsing documentation states that
Every other non-standard prop will be transferred over to the
extendedProps hash in the Event Object.
Since description and mail are not standard event properties in fullCalendar (as listed in that documentation), then they will be placed under the "extendedProps" object in the final event object which fullCalendar creates based on the data it receives from your server.
Therefore in your eventClick code you should be able to write
$('#ev_desc').html('Descripcion: ' + eventObj.extendedProps.description);
$('#ev_mail').html('Mail: ' + eventObj.extendedProps.mail);
and populate the properties successfully into your modal.
P.S. This behaviour is also mentioned in the event object documentation as well. If you have previously used fullCalendar version 3 or below, then this is a change from how these earlier versions worked.
I am trying to disable the #test button after one click in a create data table. The problem here is that I can disable it at the start but not after a click.
viewPending: function() {
createDataTable("#pTable",
{
"ajax":"test.php",
"columns": [
{
"data": "id",
"mRender": function(data, type, full) {
$("#test").on('click', function(){ //enables click event
$("#test").off('click');
$("#test").prop('disabled', true);
//alert("hello");
});
return '<div id="test" style="text-align: center"> <a id="test" class="btn btn-info btn-sm" href="'+app.api+'admin/investor/approve/'+ data +'">' + 'Approve' + '</a></div>';
}
}
]
});
},
"mRender": function(data, type, full) {
$(".test").on('click', function(){ //enables click event
$(this).parent().css("pointer-events","none"); //disable all events of pointer
});
return '<div style="text-align: center"> <a class="btn btn-info btn-sm test" href="'+app.api+'admin/investor/approve/'+ data +'">' + 'Approve' + '</a></div>';
}
}
The on click function works only when registered with document.ready function. The same wont work inside the mRender block. Move the onclick function to document.ready function and try.
I included a calendar in my project using fullcalendar.js. My database entries are showing up but they are one month ahead.
If I enter something for 16.octobre.2015, it will be saved in the database as 16.octobre.2015 but will be displayed as 16.novembre.2015. This happens with every single one of my entries.
I searched a lot here on Stack Overflow and found a few similar topics. In one, someone explained that this has something to do with how months are indexed.
PHP counts from 1 to 12.
JavaScript counts from 0 to 11.
I guess that maybe this is my problem?
Can someone tell me what I need to change, so that my entries show correctly? Here is my code:
<!-- inline scripts related to this page -->
<script type="text/javascript">
jQuery(function($) {
/* initialize the external events
-----------------------------------------------------------------*/
$('#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: $.trim($(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
$(this).data('eventObject', eventObject);
// 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
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
<?php
print "var date = new Date();\n";
print "var d = date.getDate();\n";
print "var m = date.getMonth();\n";
print "var y = date.getFullYear();\n";
print "var unixTimestamp = Date.now(); // in milliseconds;"
?>
var calendar = $('#calendar').fullCalendar({
//isRTL: true,
buttonHtml: {
prev: '<i class="ace-icon fa fa-chevron-left"></i>',
next: '<i class="ace-icon fa fa-chevron-right"></i>'
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
<?php
$dates=getPcalInfoOfHour($gl_userid,0,0);
print "events: [\n";
for ($x=0;$x<count($dates["id"]);$x++) {
print " {\n";
print " title: '".$dates["title"][$x]."',\n";
print " start: new Date(".date("Y",$dates["start"][$x]).", ".date("n",$dates["start"][$x]).", ".date("j",$dates["start"][$x]).", ".date("G",$dates["start"][$x]).", ".date("i",$dates["start"][$x]).",0,0),\n";
print " end: new Date(".date("Y",$dates["end"][$x]+1).", ".date("n",$dates["end"][$x]+1).", ".date("j",$dates["end"][$x]+1).", ".date("G",$dates["end"][$x]+1).", ".date("i",($dates["end"][$x]+1)).",0,0),\n";
print " allDay: false,\n";
print " className: 'label-info'\n";
if ($x<(count($dates["id"])-1)) {
print " },\n";
} else {
print " }\n";
}
}
print "]\n";
?>
,
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 = $(this).data('eventObject');
var $extraEventClass = $(this).attr('data-class');
// 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;
if($extraEventClass) copiedEventObject['className'] = [$extraEventClass];
// 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();
}
}
,
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
calendar.fullCalendar('unselect');
}
,
eventClick: function(calEvent, jsEvent, view) {
//display a modal
var modal =
'<div class="modal fade">\
<div class="modal-dialog">\
<div class="modal-content">\
<div class="modal-body">\
<button type="button" class="close" data-dismiss="modal" style="margin-top:-10px;">×</button>\
<form class="no-margin">\
<label>Title </label>\
<label>$dates["title"][0]</label>\
<button type="submit" class="btn btn-sm btn-success"><i class="ace-icon fa fa-check"></i> Save</button>\
</form>\
</div>\
<div class="modal-footer">\
<button type="button" class="btn btn-sm btn-danger" data-action="delete"><i class="ace-icon fa fa-trash-o"></i> Delete Event</button>\
<button type="button" class="btn btn-sm" data-dismiss="modal"><i class="ace-icon fa fa-times"></i> Cancel</button>\
</div>\
</div>\
</div>\
</div>';
var modal = $(modal).appendTo('body');
modal.find('form').on('submit', function(ev){
ev.preventDefault();
calEvent.title = $(this).find("input[type=text]").val();
calendar.fullCalendar('updateEvent', calEvent);
modal.modal("hide");
});
modal.find('button[data-action=delete]').on('click', function() {
calendar.fullCalendar('removeEvents' , function(ev){
return (ev._id == calEvent._id);
})
modal.modal("hide");
});
modal.modal('show').on('hidden', function(){
modal.remove();
});
console.log(calEvent.id);
console.log(jsEvent);
console.log(view);
// change the border color just for fun
//$(this).css('border-color', 'red');
}
});
})
</script>
The answer is literally in the question. I'll just quote you:
I searched a lot here on Stack Overflow and found a few similar topics. In one, someone explained that this has something to do with how months are indexed.
PHP counts from 1 to 12.
JavaScript counts from 0 to 11.
I guess that maybe this is my problem?
Yes. If you need a finger pointed in the right direction, let's take this part of your code:
print " start: new Date(".date("Y",$dates["start"][$x]).", ".date("n",$dates["start"][$x]).", ".date("j",$dates["start"][$x]).", ".date("G",$dates["start"][$x]).", ".date("i",$dates["start"][$x]).",0,0),\n";
print " end: new Date(".date("Y",$dates["end"][$x]+1).", ".date("n",$dates["end"][$x]+1).", ".date("j",$dates["end"][$x]+1).", ".date("G",$dates["end"][$x]+1).", ".date("i",($dates["end"][$x]+1)).",0,0),\n";
More precisely this:
date("n", $dates["start"][$x])
date("n", $dates["end"][$x]+1)
Simply subtract one from the month value:
(date("n", $dates["start"][$x]) - 1)
(date("n", $dates["end"][$x]+1) - 1)
Do this everytime you output a PHP month value in a JavaScript source.
Even better, you could just use the timestamps directly (remember that JavaScript uses milliseconds):
print " start: new Date(".($dates["start"][$x] * 1000)."),\n";
print " end: new Date(".(($dates["end"][$x]+1) * 1000)."),\n";
I want to reload the page and navigate to the user's previously active tab after the user has clicked the submit button on a jquery-jtable form. What I have now reloads the page but doesn't navigate to the user's last active tab before the reload. The tabs are created using jquery ui. Here's the shortened html:
<div id="tabs">
<ul>
<li><a href='#tabs-TasksWithRisks'>Tasks With Risks</a></li>
<li><a href='#tabs-Lessons-Learned'>Lessons Learned</a></li>
</ul>
<div id='tabs-TasksWithRisks' class='tab'>
<div id="TasksWithRisksTableContainer" class="jTableContainer" style="width:100%;"></div>
</div>
<div id='tabs-Lessons-Learned' class='tab'>
<div id="LessonsLearnedTableContainer" class="jTableContainer" style="width:100%;"></div>
</div>
</div>
<script type="text/javascript">
var project_id = <?php echo $project_data['project_id']; ?>;
var modify = <?php echo $modify ? 'true' : 'false'; ?>;
$(document).ready(function() {
loadViewProjectTasksWithRisksTable('TasksWithRisksTableContainer', project_id, modify);
loadViewLessonsLearnedTable('LessonsLearnedTableContainer', project_id, modify);
</script>
function loadViewLessonsLearnedTable(ContainerID, project_id, modify, no_toolbar) {
var fields = $.extend(true, fields, LessonsLearnedFields); //copy, don't reference
fields.Responses = getLessonsLearnedResponseChildTable(ContainerID);
$('#' + ContainerID).jtable({
title: 'Lessons Learned',
paging: true,
pageSize: 100,
sorting: true,
defaultSorting: 'WBS ASC',
actions: {
listAction: config.base_url + 'data_fetch/risks_cause_by_project/' + project_id,
deleteAction: config.base_url + 'data_fetch/delete_risk/',
updateAction: config.base_url + 'data_fetch/update_lessons_learned_risk/' + project_id
},
messages: defaultRiskMessages,
fields: fields, ,
formSubmitting: function(event,data){
$('select[name=cause]', data.form).attr('name','cause[]');
location.reload(true);
return data;
}
});
$('#' + ContainerID).jtable('load');
}
I tired location.href = config.base_url + '#tabs-Lessons-Learned'; but that didn't work. Most working solutions that I found online were for bootstrap so they weren't of much help.
I found this question on stackoveflow but I wasn't able to tailor the answer to my needs.
All help is greatly appreciated.
Instead of location.reload(true); I used loaction.assign('address_I_wanted_to_go_to')
I want to create like buttons in my comment box. Problem is that
is in while loop so any button i click will update all buttons , and its
because class name of where the output comes is same for all created
buttons.
while{
some code ...
<a ><i class="glyphicon glyphicon-thumbs-up" name="like" onclick="likeAdd()" id="like" role="button"></i></a>
<script>
function likeAdd(){
$.post("ajax/add_like.php?id=<?php echo $id_koment; ?>",function(data){
if ( data =='success')
{
likeGet()
}
else
{
alert(data);
}
});
}
function likeGet(){
$.post("ajax/get_like.php?id=<?php echo $id_koment; ?>",function(data){
$(".likeCount").text(data);
class of span for js
});
}
</script>
<span class="likeCount"> 0 </span>
class of span
} end of while
Pass the ID around as a parameter, rather than hard-coding it in your functions. e.g in pseudo-code
while (... as $id) {
<i onclick="likeAdd(<?php echo $id ?>);">
}
function likeAdd(id) {
$.ajax('/script.php?id=' + id, ....);
}