jquery használata modulban

makgab képe

Üdv!

Akkor eager jogos észrevétele alapján nyitom a témát. :)
http://drupal.hu/comment/73921#comment-73921

Akkor a kérdés:
Hogyan kellene szabályosan használni jquery-t modulban? A jquery core-t hogyan kellene include-olni, hogy ne legyen ütközés?
A jquery multi modult megnézem majd, de gondolom van erre megoldás.
Nálam a jquery_update 1.7-re van állítva.

Melyik modulhoz, modulokhoz kapcsolódik a téma?: 
Drupal verzió: 
makgab képe

Csak feltettem a jqmulti modult és bekapcsoltam. A beállításokban nem csináltam semmit, csak bemásoltam egy all/libraries/jquery/jquery-2.0.3.min.js fájlt.

Próbálgattam ide-oda tenni a drupal_add_js()-t és az .info fájlban a scripts[] opciót. Hol ment, hol nem. Most az .info fájlban sincs a jquery-2.0.3.js (és a min se), valamint drupal_add_js() sincs a modulban. Működni látszik a dolog pl. a "maskedinput.js" is.
Elég csak a modult feltenni és megoldja a dolgot?

A jqmulti szerint a modulban használni kell pl. drupal_add_js()-t.
Szóval "cache clear" után is jónak tűnik.

Egy másik oldalon nem működik ezután sem pl. a "maskedinput.js".

0
0
eager képe

Well, én hoztalak úgymond ebbe az utcába, és továbbra is véleményem, amit már elmondtam a témanyitóban linkelt topicban, de ez itt olyan alapvető téma, amit nagyon sokan sokkal jobban ismernek nálam. Én nem vagyok jártas a modulfejlesztésben. Emiatt a kérdéseidet sem igazán értem; igazából a közelében sem voltam hasonló feladatnak, más talán volt:

Akkor a kérdés:
Hogyan kellene szabályosan használni jquery-t modulban? A jquery core-t hogyan kellene include-olni, hogy ne legyen ütközés?

Remélem akad modulfejlesztésben járatos kolléga, aki abból az irányból tudja megfogalmazni az állásfoglalását, amelyikből neked az kell.

0
0
makgab képe

Pl. a maskedinput.js-t az .info fájlba teszem, akkor a potx jquery linkek nem működnek, de a maskedinput megy:

# .info
scripts[] = js/jquery-2.0.3.js
scripts[] = js/jquery.maskedinput.js
scripts[] = js/maskedinput.js

(lsd. a topic-ot), összeakadnak a jquery-k.

A jqmulti modullal, alapbeállításaival viszont megy minden (drupal_add_js() nélkül is):

# .info
scripts[] = js/jquery.maskedinput.js
scripts[] = js/maskedinput.js

Bár van oldal ahol nem megy a maskedinput ennek ellenére sem. Majd meg kell néznem miben különböznek? (talán jquery_update modul nincs és emiatt?)

0
0
eager képe

Először is tisztázzuk azt, hogy mi az a jQuery és hogy működik. Aztán megnézzük, mit lehet vele tenni.

Melléklet: http://www.codeproject.com/Articles/426013/How-jQuery-works

Mi a jQuery

  1. A böngészők a mezei hardcore javascriptet értik meg.
  2. Pár embernek feltűnt, hogy mezei hardcore javascriptet kódolni nem könnyű/nem elég erőfeszítés-hatékony (nem elég lean).
  3. Kifejlesztettek egy kódolást egyszerűsítő réteget.
    • A neve jQuery lett.
    • Telepakolták hasznos dolgokkal, hogy a leggyakrabban előforduló feladatokat meg lehessen vele csinálni, méghozzá itt a lényeg: könnyen és gyorsan.
  4. A jQuery a kódban újfajta "dialektust" tesz lehetővé. Könnyebb, egyszerűbben áttekinthető dolgokat tudsz beleírni, és azt is működőképessé teszi.
  5. (A javascript parszer önmagától nem ismerné fel a jQuery-vel behozott új információkat, ahoz fog kelleni neki segítség.)

Ez a jQuery: egy mediátor réteg a böngészők javascript parszere és a kódíró emberek között, és elsősorban az emberek kedvéért készült, hogy könnyebb/jobb legyen a munkájuk. (DX, Developer eXperience?)

Hogyan valósul meg?

  1. A natúr javascriptnek vannak saját funkciói, és a jQuery további funkciókat definiál. Vegyesen használhatod őket a kódodban.
  2. Amikor jQuery-t írsz, akkor teljesen javascript syntax szerint dolgozol, csak olyan funkciókat használsz benne, amik a böngésző számára amúgy kínaiak lennének.
  3. Ezért kell egy "tolmács" réteg, aki elmagyarázza a javascript parszernek, hogy amikor te a jQuery funkcióidat beírtad, akkor mit akartál.
  4. Ez a "tolmács" a jQuery library; ezt először be kell linkelni az olyan oldalakon, ahol jQuery funkciókkal spékelt scriptet akarsz futtatni.

A jQuery library egy objektumot hoz létre a böngésző "ős objektumán", a window objecten. (Definiál egy window.jQuery-t (amit window.$-ként is el lehet érni).)

Ezen az objektumon belül vannak definiálva a jQuery funkciók. Ha van window.jQuery (emlékeztetőül: benne csücsül a sok definiált jQuery funkció), akkor van mi feldolgozza a jquery funkciókat, van tolmács.

Mit csinálnak a jQuery Pluginek?

A jQuery pluginek feltételezik, hogy van már egy window.jQuery object, és az abban lévő funkció-listát még további funkciókkal bővítik ki.

A sima jQuery libraryt belinkeled először, ez lefut, és létrehozza a default kompetencia-készletet (window.jQuery object), az utána következőnek belinkelt jquery pluginek pedig, mikor lefutnak akkor megtalálják ezt a window.jQuery objectet, és tovább bővítik, mintegy további funkciókra is megtanítják.

Az egésznek window.jQuery a neve, és ezen a néven fogja keresni aztán az oldal összes jQuery-használó összetevője.

Hol tud ez elromlani nálad?

Ott, hogy ha nem megfelelően linkelsz be jQuery librarykat.

Te a moduljaidból drupal_add_js-el meg az .info file-okból is próbáltad definiálni a jQuery library-t, ha jól értettem; ez a következőt eredményezte:

  1. A Drupal valahol a folyamat legelején hozzáadott egy jQuery libet (7-es drupal jquery_update modul hiányában a 1.4.4-es verziót, de ez most még irreleváns), mert az default viselkedés tőle.
  2. Aztán a core további összetevői meghívogattak további jQuery plugineket, pl. a core által használt jQuery once() plugint is.
  3. A Libraries modul a sites/all/librariesből is hozzáadta a plugineket, amiket talált.
  4. Talán contrib modulok is eljutottak már addig, hogy meghívogassák a nekik szükséges plugineket.

Ha figyeltünk, látjuk, hogy eddig végig az a window.jQuery object volt építgetve-bővitgetve, amit a Drupal az elején definiált. Mostanra jó kövérre hízott, végre is tud hajtani egy halom okos dolgot (pluginek által behozott funkciókat), mert már benne vannak azoknak a funkcióknak a definíciói is.

És akkor valaki jön, és a moduljából belinkel egy másik jQuery libet.

Ha semmilyen óvintézkedést nem tett, akkor annyi történik, hogy az eddig kövérre tanított window.jQuery felül lesz írva egy full alapértelmezettel (mivel ugyanaz a neve, új értéket kap a változó, előző erték kuka). Ez a frissen definiált, mondhatni újszülött jQuery object semmit nem fog még tudni az oldalról.

Az összes mindenki az előzővel beszélt. A tanárok már leléptek. Az oldal scriptjei elkezdik hívogatni azokat a funkciókat, amik csak a felülírással agyoncsapott előző window.jQuery-nek lettek megtanítva. Viszlát. Nem fog működni.

(Legalábbis én ezt értettem meg ebből (amikor mondja, hogy a "The once() function was added to the jQuery object which was destroyed"): https://drupal.org/node/995268#comment-7202002)

Megoldás

A Drupal tapasztalati pontjaim száma továbbra is relatíve alacsony, így azt tudom mondani, hogy én csak a jquery_update és jqmulti modulokkal manipulálnám a window.jQuery object karrierjét. Azok kiforrott, biztonságos contrib modulok, olyan szakemberek írták őket, akik tudták, hogy mit csinálnak.

Pl. a jqmulti szerzőjének ki kellett módolnia, hogy egyszerre két jQuery object is jelen tudjon lenni runtime-kor (így mondják?), és ráadásul megtalálják mindkettőt a scriptek, melyiknek melyik kell. Meg van oldva szakember által. Akkor én ezzel már a modulomból nem próbálkoznék.

A jquery_update-hez annyit, hogy okos óvatossággal emelgesse az ember a jquery verziót, mert ezt a modult használva minden scriptnek az emelt verziójú jQuery jut, és régebben írt scriptekben (akár core, akár contrib összetevőkben) ez nem minden funkciónak tetszhet, szóval figyelni kell.

Jqmultival kapcsolatban annyit tudnék mondani, hogy semmivel sem tudok többet, mint ami a README-jében le van írva. Egyszer mintha használtam volna... Emlékszem, írtad, hogy a beállítófelületéhez nem nyúltál... szerintem azt pedig kell, mert valahol meg kell mondani neki, hogy melyik scriptek legyenek a ráadásként jelenlévő, emelt verziójú jQuery objecthez rendelve (hogy a többit békén tudja hagyni).

Szóval alaposan olvasd el a modul project-oldalát és readme-jét.

Ha ezen kívül van további lehetőség és módszer a fentiek megoldására Drupal használatakor, akkor annak ismertetése már tényleg a tapasztaltak dolga kell hogy legyen.

1
0
makgab képe

Köszönöm a súgót! Én is kb. így tudtam ezeket. De most megerősítettél.
Csak azt nem értem, ha nincs bekapcsolva a jqmulti-ban egyik library sem, akkor miért működik az egyik site-on, a másikon meg nem.

Ez a beállítási oldal nálam (jqmulti):

Hiába kapcsolom be a "Load this Jquery library even..." opciót nem változik a helyzet, a maskedinput.js nem működik. Vagy hiányzik még valami?

De majd utána nézek. :)

Kösz még1x!

0
0
eager képe

Azt hiszem, hogy jqmultival azokat a scripteket tudod a modernebbik jQuery-n keresztül hajtani, amiket a sites/all/libraries-be tettél. (ha a sites/all/librariesbe helyezed át a modulod .js file-ját, akkor jelenik meg ott csekkbox-al mellette, hogy az az újabbat használja).

Hogy ilyen esetben a modulodból hogy kell linkelni, vagy kell-e, vagy mi olyankor a helyzet, azt nem tudom...

EDIT:

ja, nem, többféle módja is van, tessék:

http://drupalcode.org/project/jqmulti.git/blob/refs/heads/7.x-1.x:/READM...

0
0
eager képe

jQuery használata modulban

(hogy a kérdésre is válaszoljak)

Kijavíthatom a kérdést? Ilyenre: jQuery funkciók használata modulok által definiált scriptekben.

  1. A modulodban kell valamit js-el intézni.
  2. A jQuery "dialektus" használata mellett döntesz, mert azt jobban ismered.
  3. Fogsz egy .js kiterjesztésű file-t, beteszed a modulod könyvtárába, és beleteszed azt, amit úgy hívnak, hogy "immediately invoked anonymous function, that will alias the jQuery namespace to $" Ez a Zen smink default js file-jában (némileg felokosítva) így néz ki:
      (function ($, Drupal, window, document, undefined) {
        // Ide jön majd a kódod.
      })(jQuery, Drupal, this, this.document);
  4. drupal_add_js-el, vagy #attached-el meghívod, amikor kell (vagy a modul .info file-jába teszed, nem tudom, nem fejlesztek modulokat).
  5. Így a Drupal core által biztosított 1.4.4-es jQuery library-n lesz áthajtva a kód, ennek írhatsz jQuery-t (olyan funkciókat, amit ez a verzió megért).

Most jön az, hogy kell-e neked modernebb verzió, és mennyire legyen modernebb.

  • Ha csupa olyan dolgot kell megvalósítanod, amit az 1.4.4 funkcióival is könnyen meg lehet, akkor kezdhetsz is dolgozni, semmi variálás nem kell.
  • Ha olyasmit kell csinálnod, amihez újabb jQuery funkciók kellenének, akkor meg lehetne nézni, hogy melyik a legkisebb jQuery library verzió, amely már ismeri az(oka)t a funkció(ka)t.
  • Ha 1.8-as alattiak, akkor dönthetsz a jquery_update használata mellett is, ez a modul addig feltornázza az oldal egyetlen jQuery libjét 1.8-ig, ha kell (óvatosan, írtam a másik kommentemben).
  • Ha még 1.8-ban se lenne meg, ami neked kell, vagy nem akarod kockáztatni az oldal régebbi funkciókat használó összetevőinek egészségét, akkor jön a jqmulti, ami a default 1.4.4 lib mellé behoz még egyet, és kiválaszthatod, hogy mely scriptek legyenek a modernebben keresztül hajtva.

Szóval szerintem így dönteném el, hogy mikor melyik megoldáshoz folyamodjak. Ha 1.4.4 által ismert funkciókkal is meg tudom oldani, miért ne oldjam meg úgy? Az a legkevesebb fejfájás, mind a backend, mind a frontend teljesítményt az hagyja békén a leginkább.

0
0
makgab képe

A saját problémámra találtam megoldást a masked_input modulban.

* masked_input modul telepítés (alapbeállítás jó),
* Fájl másolása ide: sites/all/libraries/maskedinput/jquery.maskedinput-1.3.js

* A saját kódban pedig használni, pl.:

libraries_get_path('maskedinput') . '/jquery.maskedinput-1.3.js';
...
$form['phone'] = array(
  '#type' => 'masked_input',
  '#mask' => '+ ?999999999999999',
...

Szépen működik.

0
0
Sk8erPeter képe

Korábbiakra:

Alapvetően kerülendő az, hogy két jQuery-változatot is használj azonos oldalon. Ha nagyon muszáj (inkább ne legyen az), akkor megoldható saját kliensoldali kódból a jQuery.noConflict() használatával, vagy az említett modullal, ami épp ezt alkalmazza. Általában a jQuery Update által frissített jQuery-változat megfelel a legtöbb igénynek, ritka eset, amikor valóban kényszermegoldásokhoz kellene folyamodni a még frissebb jQuery-verzió használata érdekében.

A kódra:

  1. libraries_get_path('maskedinput') . '/jquery.maskedinput-1.3.js';

Ez a sor így ebben a formában igazából semmire nem jó, csupán összeállít egy stringet, és semmi nem kezd vele. Szóval rossz a példakód a projekt oldalán is (ami mondjuk fura)... A libraries_get_path() csak visszaad egy stringet, konkrétan az adott könyvtár elérési útját, tehát ezt el kellene tárolni egy változóban, vagy közvetlenül átadni egy függvényhívásnak paraméterként, és kezdeni vele valamit (drupal_add_js() használatakor úgy kellene átadni, hogy hozzá kellene még ehhez az elérési úthoz fűzni egy perjelet, meg a konkrét beillesztendő fájl nevét is).
A Libraries API 2.x-ben már betölthető libraries_load() függvénnyel az adott könyvtár, és egyéb lehetőségek is vannak: https://drupal.org/node/1342238. Szóval az egyik módszerként az említett libraries_load()-dal lehetne betölteni a könyvtárat, nem pedig az idézett módon.

Az említett sor tehát nyugodtan kiszedhető, a kódodban a $form tömbhöz hozzáadott '#type' => 'masked_input' és '#mask' => '+ ?999999999999999' a lényeg:
http://drupalcode.org/project/masked_input.git/blob/3724b094a89733f020cc...
ha ezt megnézed, a hook_element_info() implementációját láthatod a masked_input_element_info() függvényben (hasonlóan a system_element_info()-éhoz), ez játszik ebben szerepet (hozzáad egy új Form API elemtípust).

Ja, és hátha érdekel még, a drupal_add_library() segítségével a megfelelően definiált könyvtárakat tudod egyszerűen hozzáadni, például a core-ban is benne lévő jQuery UI Accordiont így:
  drupal_add_library('system', 'ui.accordion');
ez még ezzel kapcsolatban hasznos lehet:
http://drupal.stackexchange.com/questions/18443/using-drupal-7-built-in-...

Kicsit hosszú lett a hsz., de remélem, ez tisztáz egy-két dolgot a témában, kérdezz, ha érdekelne még valami.

0
0
makgab képe

Köszönöm! Jogos volt az észrevétel. Gyakorlatilag, akkor az alap jquery-t használja így a "masked_input" form elem. :)

0
0