Ajax request from overridden component of joomla template - php

I'm new guy in joomla and i was searching for the answer a lot of time, but didn't get the result. I have my template in joomla 3.4.5 and i have overridden component com_content and category inside it. I made my file blog.php where i output my calendar. The problem is to send ajax changing month by clickng proper button. There is an error, when i'm trying to send ajax. Seems like joomla bans direct request. I read many articles, like how to use ajax in modules and components, but there is no advice how to use it in overriden component. Please give me detailed answer for my problem.
JHtml::_('jquery.framework');
$document = JFactory::getDocument();
$document->addScript('/space/media/media/js/mainscript.js');
i used that code to include my scriptfile in blog.php
function getAjaxData()
{
echo 'login: ' .$_REQUEST['month'] . '; password: ' . $_REQUEST['year'];
exit;
}
created method to handle my ajax request in blog.php
var j = jQuery.noConflict()
j(document).ready(function(){
j('#next').click(function(){
var month = j(this).data('month');
var year = j(this).data('year');
if(month == 12){
year +=1;
month = 1;
}
else{
month++;
}
j.post("/space/templates/forte/")
j.ajax({
url: "index.php?option=com_content&view=category&task=getAjaxData&format=raw",
type: "POST",
data: {
month: month,
year: year
},
success: function(data){
j('#calendar_wrap').html(data);
}
});
console.log('month: '+month+' year: '+year);
})
j('#prev').click(function(){
var month = j(this).data('month');
var year = j(this).data('year');
if(month == 1){
year -=1;
month = 12;
}
else{
month--;
}
j.ajax({
url: "index.php?option=com_content&view=category&task=getAjaxData&format=raw",
type: "POST",
data: {
month: month,
year: year
},
success: function(data){
j('#calendar_wrap').html(data);
}
});
console.log('month: '+month+' year: '+year);
})
});
mainscript.js, included in blog.php
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/
here is the error outputted to browser console

I solve problem with that error by putting that method:
public function getAjaxData()
{
}
In file: /site/components/com_content/controller.php
but, i have one more problem now.
In that method my calendar outputs again, but now we have new values, send by ajax. The code below:
public function getAjaxData()
{
JHtml::_('jquery.framework');
$document = JFactory::getDocument();
$document->addScript('/space/media/media/js/mainscript.js');
function days_in_month($month, $year)
{
// calculate number of days in a month
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
}
// get number of days in needed month
$currentYear = date('Y');
$currentMonth = date('n');
if(isset($_REQUEST['year']))
$currentYear = $_REQUEST['year'];
if(isset($_REQUEST['month']))
$currentMonth = $_REQUEST['month'];
$rusmonth = array('Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь');
$dayofmonth = days_in_month($currentMonth, $currentYear);
// count for days in month
$day_count = 1;
// 1. first week
$num = 0;
for($i = 0; $i < 7; $i++)
{
// get day of week
$dayofweek = date('w',
mktime(0, 0, 0, $currentMonth, $day_count, $currentYear));
// format our values to 1-monday, 6-saturday
$dayofweek = $dayofweek - 1;
if($dayofweek == -1) $dayofweek = 6;
if($dayofweek == $i)
{
// if numbers of week are equal,
// put values into array $week
$week[$num][$i] = $day_count;
$day_count++;
}
else
{
$week[$num][$i] = "";
}
}
// 2. other weeks of month
while(true)
{
$num++;
for($i = 0; $i < 7; $i++)
{
$week[$num][$i] = $day_count;
$day_count++;
// if we got the end of the month exit from loop
if($day_count > $dayofmonth) break;
}
if($day_count > $dayofmonth) break;
}
// 3. output array $week
echo '<div> <span id="prev" data-month="'.$currentMonth.'" data-year="'.$currentYear.'"><</span> '.$rusmonth[$currentMonth-1].' <span id="next" data-month="'.$currentMonth.'" data-year="'.$currentYear.'">></span> </div>';
echo '<div id="calendar_wrap">';
echo '<table border=1>';
echo '<tr>
<th>ПН</th>
<th>ВТ</th>
<th>СР</th>
<th>ЧТ</th>
<th>ПТ</th>
<th>СБ</th>
<th>ВС</th>
</tr>';
for($i = 0; $i < count($week); $i++)
{
echo "<tr>";
for($j = 0; $j < 7; $j++)
{
if(!empty($week[$i][$j]))
{
if($j == 5 || $j == 6)
echo "<td><font color=red>".$week[$i][$j]."</font></td>";
else echo "<td>".$week[$i][$j]."</td>";
}
else echo "<td> </td>";
}
echo "</tr>";
}
echo "</table>";
echo '</div>';
exit;
}
in that method i can't add my script again to get new month.
So there are two ways for me as I see:
1. make my method that way, so he become something like a bridge between blog.php and ajax. There will be no outputs.
Find a way, how could i add script to controller and make double code.
The problem is, that i have no idea, how realize both of it in Joomla...
Of course i prefer 1st variant.

Related

Arrays with javascript and php

I have this function that creates textareas deepening on the month. So if it is march, then 31 textareas. But the problem is right now that I cannot add anything into my db. I tried to make my function into arrays, and he change my php so it is like the function. But im not sure on where the issue lies. The problem is that it inserts empty values in the MySQL db.
function:
var showDate = new Date();
var months = ["Januari", "Februari", "March", "April", "May", "June",
"July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday","Monday","Tuseday","Wednesday","Thursday","Friday","Saturday"];
function drawTable(forDate) {
const daysInMonth = new Date(
forDate.getFullYear(),
forDate.getMonth() + 1,
0
).getDate();
const date = [
forDate.getFullYear(),
(forDate.getMonth() + 1 + '').padStart(2, 0)
]
.join('-');
const table = document.getElementById("table");
table.innerHTML = "";
for (let day = 1; day <= daysInMonth; day++) {
const dateString = date + '-' + (day + '').padStart(2, 0);
const row = document.createElement("tr");
const cell = document.createElement("td");
const textarea = document.createElement("textarea");
textarea.setAttribute("name", "day[]");
textarea.setAttribute("value", dateString);
textarea.innerHTML = dateString;
textarea.setAttribute("placeholder", day);
cell.appendChild(textarea);
row.appendChild(cell);
table.appendChild(row);
}
return table;
}
window.onload = function() {
document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
drawTable(showDate );
};
function daysInMonth(month, year) {
var days;
switch (month) {
case 1: // Feb, our problem child
var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
days = leapYear ? 29 : 28;
break;
case 3:
case 5:
case 8:
case 10:
days = 30;
break;
default:
days = 31;
}
return days;
}
php:
<?php
$days = $_request['day'];
echo $error = "day is empty";
if(is_array($days)){
foreach ($days as $day) {
$day = mysqli_real_escape_string($conn, $day);
if (empty($day)) {
echo $error;
}
else {
!mysqli_query(
$conn, "INSERT INTO table (day) VALUES('$day')");
}
}
}
if (count($error)) {
print_r($error);
}
?>
html:
<h1 id="displayingMonth"></h1>
<form action="index.php" method="post">
<table id="table"></table>
<input id="btn" type="submit" value="Press" />
</form>
I get my error msg: "day is empty"
Having a look at this line
textarea.setAttribute("name", "day[]");
you are in fact passing the day array to PHP
Change your PHP to this:
<?php
if (isset($_POST['submit'])) {
$error = '';
$days = $_POST['day'];
if (is_array($days)){
foreach ($days as $day) {
$day = mysqli_real_escape_string($conn, $day);
echo $day . '<br />';
if (empty($day)) {
echo $error;
} else {
mysqli_query($conn, "INSERT INTO table (day) VALUES ('$day')");
}
}
}
if (count($error)) {
print_r($error);
}
}
?>
The code checks if the submit button has been pressed (add name="submit" to your submit button) and then retrieves the day array submitted in the POST. You should consider changing $_REQUEST to $_POST, as this is a POST request. Note the uppercase $_REQUEST as opposed to $_request. The latter gave an error for me, so perhaps you don't have errors enabled. Try adding
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
to the top of your PHP script and setting
`display_errors = on`
inside your php.ini file.
Hope this helps!

Highlight td elements with events

I am generating a calendar via PHP date() function, I also have an events table that has a name and date_start, what I want to do is to highlight the td elements that have events on them and leave the ones without with the basic formatting.
Basically, this is the script that loops the day:
<?php
echo "<tr>";
for ($i = 1; $i < $numDays+1; $i++, $counter++) {
$timeStamp = strtotime ("$year-$month-$i");
if($i == 1){
$firstDay = date ("w", $timeStamp);
for ($j = 0; $j < $firstDay; $j++, $counter++){
//blank space
echo "<td> </td>";
}
}
if($counter % 7 == 0 ){
echo "<tr></tr>";
}
$todayDate = date("Y-m-d");
if (date("Y-m-d", $timeStamp) == $todayDate) {
?>
<td class="today-date"><?php echo $i; ?></td>
<?php
} else {
?>
<td><?php echo $i; ?></td>
<?php
}
}
echo "</tr>";
?>
.today-date is a class to highlight the current day. This is my table columns:
id | name | description | date_start | date_end | time | pastor_id | pastor | category | venue
I would probably put my events into an array with a key for the start date, so you end up with something like:
$events = [
'2017-08-22' => [
'name' => 'Event Title',
],
'2017-08-28' => [
'name' => 'Event Title',
'name' => 'Event Title',
],
];
There are multiple ways of doing this from a DB. Something like this:
$events = [];
while($row = mysql_fetch_assoc($eventQuery))
{
$events[$row['start_date']][] = $row['name'];
}
Then in your loop, you can check the date for an event and put it in:
<td class="<?php echo (array_key_exists(date("Y-m-d", $timeStamp), $events)) ? 'has-event-class' : ''; ?>">
Making database queries for every day in the calendar will be very inefficient compared to pulling all, or even the months'.
I would also be inclined to move this into a function so it's not as long in your loop:
function highlightEventTD($timeStamp, $events)
{
$date = date("Y-m-d", $timeStamp);
return (array_key_exists($date, $events)) ? 'has-event-class' : '';
}
Then in your forloop:
<td class="<?php echo highlightEventTD($timeStamp, $events); ?>">
It also means that if you need to show the name of the event, you can use the same array and a function:
function getEvents($timestamp, $events)
{
$date = date("Y-m-d", $timeStamp);
return (array_key_exists($date, $events)) ? $events[$date] : null;
}
Ok, first of all, PHP7 doesn't like anymore open and close php tag many times... I changed syntax with echo.
So try this :
// here make a SQL query (only one query is enough)
// on your database, for example :
$dates = array();
$q = "SELECT * FROM `events`";
if($res = $pdo->query($q) {
if($res = $res->fetchAll(PDO::FETCH_OBJ)) {
if(sizeof($res) > 0) {
foreach($res as $k => $d) {
$events[$d['date_start']] = $d;
}
}
}
}
echo "<tr>";
for ($i = 1; $i < $numDays + 1; $i++, $counter++) {
$timeStamp = strtotime ("$year-$month-$i");
if($i == 1){
$firstDay = date ("w", $timeStamp);
for ($j = 0; $j < $firstDay; $j++, $counter++) {
echo "<td> </td>"; //blank space
}
}
if($counter % 7 == 0 ) {
echo "<tr></tr>";
}
if (date("Y-m-d", $timeStamp) == date("Y-m-d")) {
$class = "today-date ";
}
if (array_key_exists(date("Y-m-d"), $events)) {
$class .= "event-date ";
}
// 1. solution based on your code
echo "<td class=\"$class\">$i</td>";
// 2. alternative with events in each day :
echo "<td class=\"$class\">";
if(sizeof($eventsOfTheDay = $events[$d['date_start']]) > 0 {
foreach($eventsOfTheDay as $k => $event) {
echo '', $event['name'], '<br>';
}
}
echo "</td>";
}
echo "</tr>";

Check for multiple rows - PHP & MySQL

I am cycling through cells in a HTML table using PHP to color specific cells.
I want to color the cells that return true to this statement:
if ($currentCell >= $reservationStartDayOfMonth && $currentCell <= $reservationEndDayOfMonth) {
make red
} else {
make normal color
}
This is not the exact statement, but the idea of it.
I get the reservationEndDayOfMonth and reservationStartDayOfMonth from a MySQL server.
For each row in the SQL server, there is a new reservation with a start and an end date. Along with the id (1...2...3...)
Basically I got a reservation in the current month. And it works when I just cycle through the cells with the data from ONE reservation. But I got lots of reservations in my database. I need to check and see if the current cell corresponds to any of the many reservations I have.
My code is long and bulky. It's basically just a table with all the checkers and parameters inside. Here you go:
<table border="1" id="calendar">
<?php
$dk_database = array("Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December");
$dk_month = $dk_database[(int)date("m")-1];
ECHO '<caption><h1 style="color:#554100;">' . $dk_month . '</h1></caption>';
$sqldateStart = sqlRequest("SELECT res_datestart FROM spottrup_reservations WHERE res_id = 1");
$dateStartRaw = mysql_fetch_array($sqldateStart);
$dateStartArray = explode("-", $dateStartRaw[0]);
$dateStartDay = (int)$dateStartArray[2];
$dateStartMonth = (int)$dateStartArray[1];
$dateStartYear = (int)$dateStartArray[0];
$sqldateEnd = sqlRequest("SELECT res_dateend FROM spottrup_reservations WHERE res_id = 1");
$dateEndRaw = mysql_fetch_array($sqldateEnd);
$dateEndArray = explode("-", $dateEndRaw[0]);
$dateEndDay = (int)$dateEndArray[2];
$dateEndMonth = (int)$dateEndArray[1];
$dateEndYear = (int)$dateEndArray[0];
$currentYear = (int)date("y")+2000;
$currentDate = (int)date("d");
$currentMonth = (int)date("m");
$columnsInRow = 7;
$daysInMonth = date("t");
$currentDay = 1;
for ($i=0 ; $i < $daysInMonth ; $i++) {
ECHO '<tr class="cal">';
for ($j=0 ; $j < $columnsInRow && $currentDay <= $daysInMonth ; $j++) {
if($currentDate==$currentDay) {
if($currentDay>=$dateStartDay && $currentDay<=$dateEndDay && $currentMonth==$dateStartMonth && $currentYear==$dateStartYear) {
ECHO '<div style="background:blue;height:100%;width:100%text-decoration:none;"><td class="cal"><h2 style="color:red;">' . $currentDay . '</h2></td></div>';
}else{
ECHO '<div style="background:#D4BB6A;height:100%;width:100%text-decoration:none;"><td class="cal"><h2 style="color:red;">' . $currentDay . '</h2></td></div>';
}
}else{
if($currentDay>=$dateStartDay && $currentDay<=$dateEndDay && $currentMonth==$dateStartMonth && $currentYear==$dateStartYear) {
ECHO '<div style="background-color:blue;height:100%;width:100%text-decoration:none;"><td class="cal" style="background-color:#FF8080;"><h2 style="color:#554100;">' . $currentDay . '</h2></td></div>';
}else{
ECHO '<div style="background-color:#D4BB6A;height:100%;width:100%text-decoration:none;"><td class="cal"><h2 style="color:#554100;">' . $currentDay . '</h2></td></div>';
}
}
$currentDay++;
}
ECHO '</tr>';
}
?>
The sqlRequest(string); calls a function that returns the result of the query you give.
Not the most efficient way since lots of queries but it does reduce a for loop, but you could run a query for each day to see if there is a reservation for it. Simple to implement.
for ($i=0 ; $i < $daysInMonth ; $i++)
{
...
$query = "Select * from table where currentDate >= startDate and currentDate <= endDate"
...
}

TimeFrame Statistic Issue

I'm having a problem regarding a time frame statistic as you see here: http://www.ivao.ch/rfe_gva/stats . I don't know why but from 1200 to 1300z I've all the flight and this is not correct..I wanna see only the flight for that time..
<?php
for ($i=8;$i<18;$i++) {
if ($i % 2 == 0) {
echo "<div class=\"row margintop20\">";
}
if ($i >= 24) {
$time = ($i-24)*100;
} else {
$time = $i*100;
}
$time100 = $time+100;
?>
How can i solve this problem?

Sometimes the contents load and sometimes they don't

I have the script below and on the website http://cacrochester.com, sometimes the contents of the right sidebar load and sometimes they don't. I think it's if it's your first few times on a page, it will say no events scheduled.
I'm completely stumped on why this is happening. The data in the database is not changing.
Let me know if you need me to post anymore code.
Thanks for helping!
<?php
$dummy = 0;
$headingLength = 0;
$descriptionLength = 0;
$shortHeading = 0;
$shortDescription = 0;
$todayYear = date('Y');
$todayMonth = date('m');
$todayDay = date('d');
$events = new dates();
$noEvents = 0;
//get the number of upcoming events
$numEvents = $events->getNumberEvents();
//get the actual events
$results = $events->getRows();
//used if there are not at least 5 events to fill up the event scroller
switch($numEvents) {
case 1: $dummy = 4; break;
case 2: $dummy = 3; break;
case 3: $dummy = 2; break;
case 4: $dummy = 1; break;
}
//loops through all of the events in the table and adds them to the list
foreach($results as $result)
{
$strippedHeading = stripslashes($result['heading']);
$strippedDescription = stripslashes($result['description']);
$headingLength = strlen($strippedHeading);
$descriptionLength = strlen($strippedDescription);
$shortHeading = $strippedHeading;
$shortDescription = $strippedDescription;
$time = strftime("%l:%M %P", $result['time']);
$location = $result['location'];
$startDate = getdate($result['start_date']);
$today = getdate();
//if the events are NOT in the past...
if($startDate >= $today)
{
//if we are at the end of the array, add the class 'last' to the li
if(current($result) == end($result))
{
echo "<li class=\"last\"><h4>".$shortHeading."</h4><h6>$time</h6><h6>$location</h6></li>".PHP_EOL;
}
else
{
echo "<li><h4>".$shortHeading."</h4><h6>$time</h6><h6>$location</h6></li>".PHP_EOL;
}
$noEvents = 1;
}
//if there is not at least 5 events, it repeats the events in the list until there are 5 total
elseif($dummy > 0 && $numEvents > 0)
{
//if the events are NOT in the past...
if($startDate >= $today)
{
//if we are at the end of the array, add the class 'last' to the li
if($dummy == 0)
{
echo "<li class=\"last\"><h4>".$shortHeading."</h4> ".$shortDescription."</li>".PHP_EOL;
$dummy--;
}
else
{
echo "<li><h4>".$shortHeading."</h4> ".$shortDescription."</li>".PHP_EOL;
$dummy--;
}
//if we have 5 events, do not add anymore
if($dummy < 0)
{
break;
}
}
$noEvents = 1;
}
}
//if there are no events, display the no events message
if($noEvents == 0)
{
echo "<li class=\"last\"><h4>No Events Scheduled</h4></li>".PHP_EOL;
}
?>
When you do $startDate >= $today you are trying to compare two arrays, which isn't too good an idea. Just use plain timestamps and it should work fine:
$startDate = $result['start_date'];
$today = strtotime('today');
Also, I'm not sure if this is a typo: current($result) == end($result), but shouldn't it be $results, which is the array name?

Categories