Witam, piszę aplikacje/komponent do systemu Joomla i napotkałem pewien problem związany z Ajax.
Jednym z elementów mojej aplikacji jest generowanie PDF'ów i właśnie przy tym napotkałem na problem. Problem polega na tym, że podmieniam pewien fragment kodu HTML, a konkretnie elementy input type="button" strony poprzez Ajax i właśnie po takiej podmianie przyciski nie reagują na kliknięcia.
Program działa na takiej zasadzie, że na stronie mamy trzy zakładki (page-mail0*), do każdej z zakładek przypisany jest inny plik. Jeżeli klikniemy w jakąś załadkę uruchamiana jest funkcja pdfexists() [plik pdf.json.php], która sprawdza czy istnieje dany plik i w zależnosci od tego wyświetlane są konkretne przyciski. Po kliknięciu w przycisk który tworzy plik PDF (tworzenie pliku obsługuje funkcja createPdf), tworzony jest plik PDF na razie przykładowy, a przyciski poprzez zmienną html wysyłane są przy pomocy json_encode i podmieniane (pdf.js). Analogiczna sytuacja ma miejsce w przypadku pliku usuwania pliku (erasePdf), a także przy sprawdzaniu czy istnieje (pdfexists). Funkcje jQuery uruchamia kliknięcie w elementy o klasie (pdftrigger). Do tworzenie pliku PDF wykorzystuję bibliotekę FPDF.
Problem polega na tym, że jeżeli odświeżę stronę to do pierwszego klinięcia w element z klasą pdftrigger wszystko działa. Jeżli strona zostanie odświeżona to np. jeżeli chcę utworzyć plik PDF to po kliknięciu w przycisk plik się tworzy, jeżeli natomiast chciałbym go skasować to kliknięcie w przycisk już nie działa. Muszę odświeżyć stronę i wtedy mogę kliknąć w przycisk, plik się usuwa, jednak nie mogę go już utworzyć. Muszę ponownie odświeżyć stronę. Mogę natomiast klikać w zakładki, zawsze wyświetla mi się prawidłowa, niezależne od tego ile razy będę klikał w element z data-toggle="tab". Jednak po kliknięciu w niego nawet jeżeli nie klikałem wcześniej w przycisk kliknięcie w przycisk nic nie daje. Zapewnie jest to związane z tym, że równie elementy data-toggle="tab" posiadają klasę pdftrigger.
Poniżej zamieszczam fragmenty kodu. Ajax podobnie jak jQuery jest technologią do której dopiero się wdrażam i nic jeszcze w niej nie tworzyłem, więc proszę o wyrozumiałość.
Mam nadzieje, że wyjaśniłem wszystko w miarę zrozumiale. Pozdrawiam i proszę o pomoc.
PS. W dużym skrócie wygląda to tak, że po podmianie fragmentu kodu html poprzez jQuery, klikanie w podstawione elementy nie jest już wykrywane.
default.php - główny plik. Znajduje się tutaj część kodu która przy pierwszym uruchomieniu strony sprawdza czy plik istnieje, a także zakładki które wyświetlają zawartość w zależności od ich wybrania.
<div class="pdfsection">
<?php if (file_exists($file_name)) : ?>
<input type="button" rel="downloadPdf" class="btn btn-primary pdftrigger" value="<?php echo JText::_('COM_ZLECENIA_DOWNLOAD_PDF'); ?>">
<input type="button" rel="erasePdf" class="btn btn-danger pdftrigger" value="<?php echo JText::_('COM_ZLECENIA_ERASE_PDF'); ?>">
<?php else : ?>
<input type="button" rel="createPdf" class="btn btn-primary pdftrigger" value="<?php echo JText::_('COM_ZLECENIA_GENERATE_PDF'); ?>">
<?php endif; ?>
</div>
<input type="hidden" name="order_id" value="<?php echo $order->order->order_id; ?>" />
<ul class="nav nav-tabs">
<li class="active" >
<a href="#page-mail01" class="pdftrigger mail01" rel="pdfexists" data-toggle="tab"><?php echo JText::_('COM_ZLECENIA_ORDERS_MAIL_OFFER_TAB_TITLE'); ?></a>
</li>
<li>
<a href="#page-mail02" class="pdftrigger mail02" rel="pdfexists" data-toggle="tab"><?php echo JText::_('COM_ZLECENIA_ORDERS_MAIL_OFFER_SHORT_TAB_TITLE'); ?></a>
</li>
<li>
<a href="#page-mail03" class="pdftrigger mail03" rel="pdfexists" data-toggle="tab"><?php echo JText::_('COM_ZLECENIA_ORDERS_MAIL_ORDER_TAB_TITLE'); ?></a>
</li>
</ul>
<div class="tab-content">
<div id="page-mail01" class="tab-pane active">
<?php echo $mail['mailOffer']; ?>
</div>
<div id="page-mail02" class="tab-pane">
<?php echo $mail['mailOfferShort']; ?>
</div>
<div id="page-mail03" class="tab-pane">
<?php echo $mail['mailOrder']; ?>
</div>
</div>
pdf.js - plik z kodem javascript/jquery obsługujący te kliknięcia
(function($){
$(document).ready(function(){
$(".pdftrigger").click(function(){
alert('test');
var $this = $(this);
var action = $this.attr('rel');
var order_id = document.getElementsByName("order_id")[0].value;
if (action == 'pdfexists') {
var active = $this.attr('class')[16];
} else {
/* Wybranie aktywnej karty i obliczenie typu wiadomości */
var Tabs = document.getElementsByClassName("nav-tabs")[0].getElementsByTagName("LI");
var active = 0;
for (index = 0; index < Tabs.length; index++) {
if (Tabs[index].className == "active") {
active = index + 1;
}
}
}
$.post(
'index.php',
{
option: 'com_zlecenia',
task: 'pdf.'+action,
format: 'json',
type: active,
order_id: order_id,
tmpl: 'raw'
},
function(respJSON) {
document.getElementsByClassName('pdfsection')[0].innerHTML = respJSON.html;
console.log(respJSON);
},
'json'
);
if (action == 'pdfexists') {
return true;
} else {
return false;
}
});
});
})(jQuery)
pdf.json.php - plik zawierający funkcje, które wywołuje jQuery
<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.controller');
class ZleceniaControllerPdf extends JControllerLegacy {
function createPdf() {
require_once(JPATH_COMPONENT . '/helpers/fpdf.php');
$index = $this->getModel('Order')->getIndex(JRequest::getInt('order_id'))->order_index;
$file_name = strtolower('images/orders/'.str_replace('/','',$index).JRequest::getInt('type').'.pdf');
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$pdf->Output('F', $file_name);
$html = '<input type="button" rel="downloadPdf" class="btn btn-primary pdftrigger" value="'.JText::_('COM_ZLECENIA_DOWNLOAD_PDF').'"> ';
$html .= '<input type="button" rel="erasePdf" class="btn btn-danger pdftrigger" value="'.JText::_('COM_ZLECENIA_ERASE_PDF').'">';
echo json_encode(array(
'status' => 'OK',
'file_name' => $file_name,
'object' => JRequest::get(),
'html' => $html
));
return TRUE;
}
function erasePdf() {
$index = $this->getModel('Order')->getIndex(JRequest::getInt('order_id'))->order_index;
$file_name = strtolower('images/orders/'.str_replace('/','',$index).JRequest::getInt('type').'.pdf');
unlink($file_name);
$html = '<input type="button" rel="createPdf" class="btn btn-primary pdftrigger" value="'.JText::_('COM_ZLECENIA_GENERATE_PDF').'">';
echo json_encode(array(
'html' => $html
));
return TRUE;
}
function pdfexists() {
//pobranie numeru aktualnego zlecenia
$index = $this->getModel('Order')->getIndex(JRequest::getInt('order_id'))->order_index;
$file_name = strtolower('images/orders/'.str_replace('/','',$index).JRequest::getInt('type').'.pdf');
if (file_exists($file_name)) {
$html = '<input type="button" rel="downloadPdf" class="btn btn-primary pdftrigger" value="'.JText::_('COM_ZLECENIA_DOWNLOAD_PDF').'"> ';
$html .= '<input type="button" rel="erasePdf" class="btn btn-danger pdftrigger" value="'.JText::_('COM_ZLECENIA_ERASE_PDF').'">';
} else {
$html = '<input type="button" rel="createPdf" class="btn btn-primary pdftrigger" value="'.JText::_('COM_ZLECENIA_GENERATE_PDF').'">';
}
echo json_encode(array(
'order_id' => $index,
'active' => JRequest::getInt('type'),
'html' => $html
));
return TRUE;
}
}