Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Joomla! Extensions (Components, Modules, Plugins)

Συντονιστές: WebDev Moderators, Super-Moderators, PHP Moderators

Απάντηση
Άβαταρ μέλους
limitCracker
Δημοσιεύσεις: 20
Εγγραφή: 28 Ιουν 2013 23:00
Επικοινωνία:

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από limitCracker » 29 Ιουν 2013 00:15

Χαίρετε παίδες,

έχω ένα προβληματάκι με την τριπλέτα AJAX-jQuery-Joomla Component

έχω φτιάξει ένα module/component για Joomla 2.5. Είναι για το παιχνίδι του ΟΠΑΠ kino.
Εν συντομία το παιχνίδι του ΚΙΝΟ για όποιον δεν ξέρει είναι το εξής: Κληρώνει 20 από τους 80 αριθμούς κάθε 5 λεπτά. Ο ΟΠΑΠ ανεβάζει το XML της κλήρωσης αμέσως με το που κληρωθεί.

Παίρνω το XML που δίνει ο ΟΠΑΠ για κάθε κλήρωση. Έχει την παρακάτω μορφή:

Κώδικας: Επιλογή όλων

<draw>
<drawNo>390951</drawNo>
<drawTime>2013-06-28T17&#58;55&#58;00+03&#58;00</drawTime>
<result>7</result>
<result>8</result>
<result>12</result>
<result>15</result>
<result>19</result>
<result>22</result>
<result>28</result>
<result>29</result>
<result>33</result>
<result>35</result>
<result>36</result>
<result>51</result>
<result>52</result>
<result>54</result>
<result>59</result>
<result>63</result>
<result>67</result>
<result>68</result>
<result>76</result>
<result>79</result>
</draw>
To module παίρνει το XML και φτιάχνει έναν πίνακα που δείχνει ποιοι αριθμοί κλρώθηκαν. Επίσης έχει και κουμπιά για να πλοηγείσαι Πίσω, Μπρος και στην Τελευταία.

Εικόνα

Το παραπάνω χωρίζεται σε δύο DIVs μέρη (α) το πάνελ με τα βέλη και (β) τον πίνακα με τα κληρωθέντα και το κουτί που λέει τον αριθμό της κλήρωσης.

Με jQuery-AJAX έχω καταφέρει να ανανεώνω το (β) σκέλος χωρίς πρόβλημα όταν πατιέται ένα από τα βέλη.

Το πρόβλημα είναι ότι όταν πατάω το κουμπί LAST υποτίθεται ότι πρέπει να ξανακάνει fetch από τον server του ΟΠΑΠ και να δείχνει την τελευταία διαθεσίμη που έχουν ανεβάσει αλλά αντί αυτού μου εμφανίζει την κλήρωση που θεωρείτω τελευταία όταν έκανε load το module.
παράδειγμα για να βγάλετε άκρη από τα παραπάνω:
-ώρα 18:00 κληρώνεται η 380 πχ. Ο ΟΠΑΠ ανεβάζει αμέσως το XML για την 380 και μπορείς να το κάνεις fetch μέσω του http://applications.opap.gr/DrawsRestSe ... o/last.xml
-ώρα 18:05 κληρώνεται η 381
-ώρα 18:07 ένας χρήστης κάνει load τη σελίδα που έχει το module πάνω. Άρα το module θεωρεί τελευταία την 381
-ώρα 18:10 κληρώνεται η 382
-ώρα 18:15 κληρώνεται η 383, ο χρήστης μέχρι αυτή την ώρα δεν έχει κάνει Refresh ή κάτι άλλο ας υποθέσουμε ότι χάζευε τις παλιές κληρώσεις
-ώρα 18:18 ο χρήστης θέλει να δει την πιο πρόσφατη κλήρωση οπότε πατάει το LAST, ξέρει ότι έχει περάσει ένα 10λεπτο κα από τότε οπότε περιμένει να δει την 383 κλήρωση αλλά αντ'αυτού βλέπει την 381.

Αυτό είναι το πρόβλημά μου εν συντομία... :P


Για να δείτε LIVE το πρόβλημα δείτε τα παρακάτω:
-XML για την τελευταία κλήρωση: http://applications.opap.gr/DrawsRestSe ... o/last.xml

-XML για μια τυχαία κλήρωση: http://applications.opap.gr/DrawsRestSe ... 390951.xml

-LIVE DEMO του module/component μου: http://kino.joomlagifts.com/


Βλέπωντας τη συμπεριφορά αυτή σκεφτόμουν ότι μπορεί να φταίει ότι κρατάω την Current, Prev, Next και Last κληρώσεις σε μεταβλητές javascript. Παρακάτω είναι το script που χρησιμοποιώ.

Κώδικας: Επιλογή όλων

<script type="text/javascript">
	var jq191 = jQuery.noConflict&#40;true&#41;;
	
        //Εδώ κάνει fetch την τελευταία κλήρωση από τον ΟΠΑΠ σερβερ την τάδε χρονική στιγμή
	var lastDrawNo = parseInt&#40;"<?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>", 10&#41;;

        //Εδώ θέτει την προσωρινή κλήρωση να είναι η τελευταία που μόλις πήρε από πάνω
	var currDrawNo = lastDrawNo;
	
	jq191&#40;document&#41;.ready&#40;function&#40;&#41;&#123;
		
                //Εδώ τίθεται ότι αν πατηθεί το Previous κουμπί τότε θα μειώσει την Current κατά ένα και θα καλέσει την AJAX 
                //function όπου κάνει κλήση στο Component όπου αυτό με τη σειρά του θα αντικαταστήσει δυναμικά το &#40;β&#41; σκέλος του module.
		jq191&#40;"#prev"&#41;.click&#40;function&#40;&#41;&#123;
			currDrawNo = currDrawNo - 1;
			if &#40;currDrawNo < 1&#41;&#123;currDrawNo = 1;&#125;
			callChooseDrawAjax&#40;  &#41;;
		&#125;&#41;;
		
                //Μια από τα ίδια με το Prev μόνο που είναι για το Next.
		jq191&#40;"#next"&#41;.click&#40;function&#40;&#41;&#123;
			currDrawNo = currDrawNo + 1;
			if &#40;currDrawNo > lastDrawNo&#41;&#123;currDrawNo = lastDrawNo;&#125;
			callChooseDrawAjax&#40;  &#41;;
		&#125;&#41;;
		
                //Εδώ είναι το πρόβλημα. Ενώ το βάζω να κάνει κλήση στον server ξανά ,αν πατηθεί το LAST κουμπί,για να πάρει την τελευταία 
                //του server ώστε να ανανεώσει αυτή που έχει το module δε το κάνει. Η κλήση γίνεται μέσω μιας function που έχει ο helper.php.
		jq191&#40;"#last"&#41;.click&#40;function&#40;&#41;&#123; //jq191&#40;document&#41;.on&#40;"click", "#last", function&#40;&#41;&#123;
			currDrawNo = <?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>;
		&#125;&#41;;
		
		jq191&#40;"#search_kino"&#41;.click&#40;function&#40;&#41;&#123;
			currDrawNo = jq191&#40;"#search_draw_txt"&#41;.val&#40;&#41;;
			callChooseDrawAjax&#40;  &#41;;
		&#125;&#41;;
		
	&#125;&#41;;
	
	
        //Αυτή είναι η function που κάνει το AJAX request. Στέλνει στο component την Current κλήρωση μέσω του data. Οπότε το component 
        //ξέρει ποια κλήρωση να αντικαταστήσει στο &#40;β&#41; σκέλος του module.
	function callChooseDrawAjax&#40;&#41;&#123;
			
		jq191.ajax&#40;&#123;
			type&#58; 'POST',
			url&#58; "<?php echo JURI&#58;&#58;root&#40;&#41;.'index.php?option=com_kino&controller=controller&task=display&format=raw' ?>",
			cache&#58; false,
			data&#58; &#123;
				draw_no&#58; currDrawNo
			&#125;,
			dataType&#58; 'text',
			success&#58; function&#40;data&#41;&#123;
			
				jq191&#40;".mod_kino_playground"&#41;.load&#40;"<?php echo JURI&#58;&#58;root&#40;&#41;.'index.php?option=com_kino&controller=controller&task=chooseDraw&draw_no='?>"
										+currDrawNo+"<?php echo '&format=raw' ?>"&#41;;
				
				
                                //Ο παρακάτω σε σχόλια κώδικας ήταν μια απόπειρα να ξανακάνω load μόνο τον eventListener για το LAST κουμπί μήπως και αξιωθεί και πάρει την 
                                //σωστή τελευταία από το server του ΟΠΑΠ. Δεν ευδοκίμησε. 
                                /*
				jq191&#40;document&#41;.on&#40;"click", "#last", function&#40;&#41;&#123; 
					jq191&#40;this&#41;.prop&#40;'src', "<?php echo JURI&#58;&#58;root&#40;&#41;.'modules/mod_kino/images/end_arrow_small_c.jpg' ?>"&#41;;
					window.currDrawNo = <?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>;
				&#125;&#41;;
				*/
			&#125;
		&#125;&#41;;
	&#125;
	
</script>

Μιά άλλη λύση που σκέφτηκα ήταν να κάνω άλλη μία function για να κάνω μέσω AJAX load και το (α) και το (β) σκέλη του module. Αλλά μετά πάμε σε άλλα. Πχ διαφορετικό layout κλπ κλπ. Θα ήθελα να πιστεύω ότι υπαρχει και πιο εύκολος τρόπος. Έχετε κάποια ιδέα τι μπορεί να κάνω λάθος?
Αν θέλετε να ποστάρω και άλλα αρχεία πείτε μου.

Άβαταρ μέλους
fafos
Script Master
Δημοσιεύσεις: 6230
Εγγραφή: 30 Νοέμ 2004 03:09

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από fafos » 29 Ιουν 2013 16:22

Fysiko einai na mhn vriskei thn teleutaia klhrosh afou thn orizeis me to pou kanei load h selida

Κώδικας: Επιλογή όλων

currDrawNo = <?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>; 
prepei na kaneis ena diaforetiko ajax-post-load gia na pairneis to "var lastDrawNo" otan kaneis click pano se kapoio apo ta tria velakia.
Οι πάνες και οι πολιτικοί πρέπει να αλλάζονται συχνά για τον ίδιο λόγο...

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από alou » 29 Ιουν 2013 17:27

Εκτός από αυτό που πολύ σωστά φυσικά λέει ο fafos, θα σου πρότεινα να επιστρέφεις πάντα από το component την html που θα χρησιμοποιήσεις και το μόνο που θα διαφοροποιείται στο ajax function να είναι το όνομα του post, για να ξέρεις και πως θα χειριστείς την διαδικασία στο component.

Δηλαδή, αν στέλνεις klirosiID σου επιστρέφεται η html της συγκεκριμένης κλήρωσης και την κάνεις append (μέσα από το success του ίδιου ajax function) στο element που θες, αν στέλνεις lastKlirosi στην php έχεις 2 βήματα: να βρείς το last id και να το κάνεις fetch, πριν το κάνεις echo για να το επιστρέψεις στην ajax function.

Επίσης, καλό θα είναι στα ajax post του joomla να χρησιμοποιείς και tokens.

Άβαταρ μέλους
limitCracker
Δημοσιεύσεις: 20
Εγγραφή: 28 Ιουν 2013 23:00
Επικοινωνία:

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από limitCracker » 29 Ιουν 2013 22:19

Καταλαβαίνω αλλά θα ήθελα λίγο να σας ρωτήσω το εξής:

#Ερώτηση 1
Όταν κάνει load το script τότε ας υποθέσουμε το lastDraw γίνεται 380.
Μετά από 10 λεπτά ο χρήστης πατάει το LastButton οπότε τρέχει η anonymous function για αυτό οπότε τρέχει ξανά το

Κώδικας: Επιλογή όλων

currDrawNo = <?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>;
όπου η getLastDrawNum() υποτίθεται ότι κάνει fetch ξανά από το server:

Κώδικας: Επιλογή όλων

function getLastDrawNum&#40;&#41;&#123;
	global $mainframe;
	$xml_kino = simplexml_load_file&#40;"http&#58;//applications.opap.gr/DrawsRestServices/kino/last.xml"&#41;;
	return $xml_kino->drawNo;
&#125;
οπότε δε θα έπρεπε να ανανεώσει την javascript μεταβλητη lastDraw στην 383?

#Ερώτηση 2
Αν κάνω reload δυναμικά ένα κουμπί τότε αυτόματα κάνει reload και ο eventListener του? Δλδ αν φέρω με AJAX το LastButton τότε θα ξανατρέξει το

Κώδικας: Επιλογή όλων

jq191&#40;"#last"&#41;.click&#40;function&#40;&#41;&#123;
		currDrawNo = <?php $lastDrawNo = mod_kino&#58;&#58;getLastDrawNum&#40;&#41;; echo $lastDrawNo; ?>;
		callChooseDrawAjax&#40; &#41;;
	&#125;&#41;;
#Ερώτηση 3
Έστω ότι πρέπει να κάνω νέο ajax-post-load θα πρέπει να φτιάξω και νέο layout στο component μου?
Το default.php το έχω για να κάνει δυναμικά reload το (β) σκέλος του module δλδ τα νούμερα και τον αριθμό της κλήρωσης.

#Ερώτηση 4
@alou
Όταν λες να βάλω άλλο όνομα Post εννοείς να βάλω μια παράμετρο στην ajax call όπου θα λέει ποιο element την κάλεσε ή εννοείς να φτιάξω νέο task στο component?

#Ερώτηση 5
Όταν λες tokens εννοείς ένα διακριτικό για να μην επαναλαμβάνεται το request?


Σας ευχαριστώ ήδη για τη βοήθειά σας :)

alou
Script Master
Δημοσιεύσεις: 1374
Εγγραφή: 24 Αύγ 2007 19:52
Επικοινωνία:

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από alou » 30 Ιουν 2013 10:35

Θα μείνω μόνο στο 1 γιατί πρέπει να καταλάβεις κάτι βασικό: όταν τρέχει η js, η php έχει ήδη στείλει ότι μεταβλητή της έχεις ορίσει. Όταν ο client παίρνει το script, δεν υπάρχει php εκεί μέσα, ο βασικός διαχωρισμός client side και server side scripts.

δηλαδή, αν σε ένα js φτιάχενεις μια μεταβλητή:
var time = "<?php echo now(); ?>

Αυτό θα στείλει ένα script στον browser, όπου δεν υπάρχει καθόλου php βεβαια μέσα αλλά μόνο μια τιμή, της ώρας που έτρεξε το php script. Δεν θα αλλάξει ποτέ αυτή η τιμή αν δεν ξαναφορτωθεί το script με reload της σελίδας (η μέσα από το ίδιο το script βεβαια).

Το currDrawNo έχει οριστεί μια φορά, μόνο αν ξανατρέξει το php script που την ορίζει θα αλλάξει και αυτό δεν γίνεται client side.

Θα μπορούσε μόνο να πάρει καινούργια τιμή είτε με refresh σελίδας ή αν έστελνες στην php ένα ajax request και ζητούσες να σου επιστραφεί το νέο last id ας πούμε.

Αυτό αφορά εν μέρει και την ερώτηση 2, ξέχνα την php μέσα στο javascript. εκεί ο browser διαβάζει την τιμή που φτιάχτηκε όταν φόρτωσε.

Για την ερώτηση 3, το φτιάχνεις όπως σε βολεύει. Δεν χρειάζεται να έχεις 10 views όμως για κάθε function, μπορείς να έχεις και μόνο ένα και όταν παίρνεις στην php τα post / get να μπορείς να βγάλεις συμπέρασμα τι πρέπει να επιστρέψεις και να κάνεις την ανάλογη δουλειά. Αν στο ajax δηλαδή κάνεις post ένα πεδίο με όνομα lastid, στην php θα πεις

$lastid = $this->incoming->post->get('lastid', 'NULL', 'STRING');
if ($lastid && $lastid !='NULL') {
//πρεπει να βρεις το lastid και να το κάνεις echo για να επιστραφεί στο ajax request
return ;
//οπότε πιο κάτω έχεις άλλα function που τσεκάρουν αν υπάρχει άλλο post
}

ή να παίξεις με το &task= και είτε να πάρεις το task με getTask είτε να τα ρυθμίσεις στο model σου είτε ότι σε βολεύει / βολεύει τη συγκεκριμένη εφαρμογή.

Αλλά αυτό το κάνεις όπως σε βολεύει, μια άλλη πρακτική - πολύ σωστή κατά τη γνώμη μου για μεγαλύτερες εφαρμογές - θα ήταν τα js πεδία που θα πρέπει να σταλούν με ajax, να κουβαλάνε το url που θα σταλούν:

<input name="tade" type="text" data-ajaxurl="index.php?option=com_tade&klpklp">

και η ajax function να παίρνει αυτό πάντα δυναμικά.

Τέλος πάντων, αν καταλάβεις το πρώτο κομμάτι θα βρεις άκρη και για τα υπόλοιπα και θα δεις και πως σε βολεύει να το κάνεις.

Για τα tokens ναι μιλάω για csrf protection, ρίξε μια ματιά στο joomla api να δεις τη χρήση τους αν θες.

Άβαταρ μέλους
limitCracker
Δημοσιεύσεις: 20
Εγγραφή: 28 Ιουν 2013 23:00
Επικοινωνία:

Πρόβλημα με κουμπί πλοήγησης σε Joomla 2.5 module-component με AJAX jQuery

Δημοσίευση από limitCracker » 30 Ιουν 2013 16:41

Ευχαριστώ φίλε μου τώρα τα έδεσα όλα. :)
Είμαι τραγικός ξέχασα τα βασικά.

Απάντηση

Επιστροφή στο “Joomla! Extensions (Components, Modules, Plugins)”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 1 επισκέπτης