Oppitunti: Kehittyneen mukautetun painovoiman kenttätyypin luominen ja useiden syöttöarvojen käsittely
Tässä opetusohjelmassa näytän sinulle, kuinka luodaan edistynyt mukautettu Gravity Forms -kenttätyyppi. Kentässä on useita syötteitä, ja se vaatii erityiskäsittelyä lähetettyjen arvojen tallentamiseksi ja näyttämiseksi.
Mitä teemme
Tässä esimerkissä oletan esimerkin WordPress-verkkosivuston omistajasta, joka käsittelee lounastoimituksia työpaikalla. Omistajalla on lomake, johon ihmiset voivat täyttää, millaisen lounaan he haluavat ja kuinka monta viikon kullekin päivälle. Tämä voidaan ratkaista taulukkomaisena tapana syöttää numero mille tahansa kurssille minä tahansa päivänä, jona he haluavat toimituksen.
Kurssit ovat muokattavissa kentän asetuksista lomakeeditorissa ja niitä voi muuttaa milloin tahansa. Ja jokaisesta lomakkeen lähetyksestä verkkosivuston omistaja saa täydellisen yleiskatsauksen lähetetyistä arvoista:
Ilmeisesti tämä on vain esimerkki, ja sinun on todennäköisesti mukautettava tämä tapauksesi mukaan. Mutta tämän esimerkkitapauksen avulla saamme mahdollisuuden oppia käsittelemään useita syötteitä yhdessä kentässä. Sen pitäisi antaa sinulle ideoita oman mukautetun kenttätyypin käsittelemiseen.
Ennen kuin aloitat koodauksen
Ennen kuin aloitamme, tarvitsemme paikan koodin lisäämiseen. Voit lisätä tämän teemaasi functions.phptai laajennustiedostoosi.
Menetelmä, jonka olen valinnut, on oliosuuntautunut, mikä tarkoittaa luokan luomista, joka laajentaa Gravity Formsin GF_Fieldluokkaa. Suosittelen sijoittamaan luokan erilliseen tiedostoon projektissasi. Sinun tulee myös tarkistaa, että Gravity Forms -laajennus on olemassa, ennen kuin sisällytät luokkasi, jotta sivustosi ei kaatuisi.
Jos olet kiinnostunut, voit katsoa Gravity Formsin dokumentaatiota GF_Fieldissä. Löydät lisää toimintoja ja muuttujia, joita saatat tarvita kenttätyypille.
Laajentamalla GF_Fieldluokkaa voimme yksinkertaisesti ohittaa funktiot, joita meidän on muutettava. Mitä tulee toimintoihin, joita emme ohita, Gravity Forms suorittaa oletusarvon, joka on määritetty sisällä GF_Field. Alla olevassa opetusohjelmassa käymme läpi jokainen toiminto, joka meidän on ohitettava mukautetussa kentässämme yksitellen. Sen enempää puhumatta, aloitetaan!
Mukautetun kenttätyypin luominen
Ensimmäinen vaihe on mukautetun PHP-luokan määrittäminen, joka ulottuu GF_Field. Anna luokalle yksilöllinen nimi ja varmista, että se sisältyy projektiisi. Luokan määrittelyn jälkeen suoritamme register()staattisen funktion GF_Fieldantamalla luokkamme esiintymän parametrina. Tämä alustaa luokkamme ja rekisteröi kenttätyypin.
Ainoa pakollinen muuttuja, jota tarvitset luokassasi, on $type. Luokkamuuttujan $typeon oltava yksilöllinen, ja se on kenttätyyppisi slug-nimi. Esimerkissäni olen antanut sille nimen " food_delivery".
if (class_exists('GF_Field')) {
class FoodDelivery extends GF_Field {
public $type = 'food_delivery';
// The rest of the code is added here...
}
GF_Fields::register(new FoodDelivery());
}
Tämän pienen koodinpätkän avulla mukautettu kenttätyyppimme tulisi lisätä Gravity Forms -editorissa käytettävissä olevaksi valinnaksi. Oletuksena se näkyy "Standard Fields" -ruudun lopussa. Koska emme ole vielä antaneet kentällemme oikeaa nimeä (se on seuraava vaihe), painike on merkitty arvoksi $type.
Kentän nimen määrittäminen
Seuraava vaihe on helppo; annamme alallemme paremman nimen. Tätä varten ohitamme funktion get_form_editor_field_title(). Meidän tarvitsee vain palauttaa merkkijono kentän nimellä.
public function get_form_editor_field_title() {
return esc_attr__('Food Delivery', 'txtdomain');
}
Tällä toiminnolla luokassamme kentän lisäyspainike päivitetään paljon paremmalla tunnisteella.
Kentän luokan muuttaminen
Tämä vaihe on valinnainen. Oletuksena mukautettu kenttätyyppimme näkyy "Standard Fields" -ruudussa, mutta voimme muuttaa sitä. Oletetaan, että haluamme sen näkyvän "Lisäkentät" -ruudussa.
Jos haluat muuttaa luokkaa, jossa haluamme kentän näkyvän, ohitamme toiminnon get_form_editor_button(). Meidän on palautettava assosiatiivinen taulukko, jossa on kaksi elementtiä. Arvona avaimelle ’ group’ annat sen kategorian sisäisen nimen, jossa haluat painikkeen näkyvän. Tässä käytettävissä olevat vaihtoehdot ovat ’ standard_fields’, ’ advanced_fields’, ’ post_fields’ tai ’ pricing_fields’. (Voit myös luoda oman kategorian, mutta sitä ei käsitellä tässä). Taulukon toinen elementti tarvitsee avaimen ’ text’ ja sitä varten yksinkertaisesti palautamme kentän nimen kutsumalla get_form_editor_field_title(). Tämä on toiminto, jonka loimme juuri yllä.
public function get_form_editor_button() {
return [
'group' => 'advanced_fields',
'text' => $this->get_form_editor_field_title(),
];
}
Nyt painike mukautetun kenttätyypin lisäämiseksi on siirretty "Lisäkentät" -ruutuun.
Aktivoidaan kenttäasetuksia
Jos olet yrittänyt lisätä kenttätyyppiä lomakkeeseen, olet ehkä huomannut, että asetuksia ei ole ollenkaan. Et voi edes muokata etikettiä. Tämä toimii siten, että kaiken tyyppiset asetukset ovat olemassa, ne on yksinkertaisesti piilotettu CSS:llä Gravity Formsin toimesta. Meidän on määritettävä erikseen, mitkä asetukset haluamme ottaa käyttöön, ja Gravity Forms näyttää sitten valitut asetukset puolestamme.
Meidän on määritettävä funktio get_form_editor_field_settings()ja palautettava joukko kaikkia asetuksia, joita emme halua piilottaa kenttätyypille. Se, mitkä asetukset haluat lisätä, on täysin sinun ja projektisi päätettävissä. Muista, että kentän tulee tukea kaikkia aktivoimiasi asetuksia, muuten ei ole mielekästä näyttää sille asetusta.
Olen luonut alle pikakatsauksen asetusten nimistä. Tämä ei ole läheskään täydellinen luettelo, koska on monia asetuksia, jotka ovat hyödyllisiä vain hyvin tietyille kenttätyypeille. Esimerkiksi puhelinmuoto, päivämäärä/aikamuoto ja joukko asetuksia, jotka liittyvät Posti- ja Hinnoittelu-kenttiin.
Yleiset-välilehti
- Kentän tunniste:
label_setting - Kentän kuvaus:
description_setting - Valinnat:
choices_setting - Vaaditaan:
rules_setting - Ei kaksoiskappaleita:
duplicate_setting - Ota sarakkeet käyttöön:
columns_setting - Ota "valitse kaikki" käyttöön:
select_all_choices_setting - Ota "muu" valinta käyttöön:
other_choice_setting
Ulkoasu-välilehti
- Paikanpitäjä:
placeholder_setting - Kenttätunnisteen näkyvyys ja kuvauksen sijainti:
label_placement_setting - Mukautettu vahvistusviesti:
error_message_setting - Mukautettu CSS-luokka:
css_class_setting - Kentän koko:
size_setting
Lisäasetukset-välilehti
- Järjestelmänvalvojan kentän tunniste:
admin_label_setting - Oletusarvo:
default_value_setting - Ota salasanan syöttö käyttöön:
password_field_setting - Pakota SSL:
force_ssl_field_setting - Näkyvyys:
visibility_setting - Salli kentän täyttäminen dynaamisesti:
prepopulate_field_setting - Ota ehdollinen logiikka käyttöön:
conditional_logic_field_setting - Ota sivun ehdollinen logiikka käyttöön:
conditional_logic_page_setting
Esimerkissämme tärkeimmät ovat kentän nimi, kuvaus, valinnat ja pakollinen kenttä vai ei. Sallimme myös CSS-luokan, mukautetun vahvistusviestin ja ehdollisen logiikan asetukset.
public function get_form_editor_field_settings() {
return [
'label_setting',
'choices_setting',
'description_setting',
'rules_setting',
'error_message_setting',
'css_class_setting',
'conditional_logic_field_setting'
];
}
Päivitä lomakeeditori, niin sinun pitäisi nyt nähdä kaikki valitut asetukset ja välilehdet kentässämme. Gravity Forms käsittelee ja tallentaa kaikki asetukset automaattisesti.
Mene eteenpäin ja lisää joitain kohteita Choices-luetteloon, jotta meillä on jotain tehtävää. Tässä on mitä olen asettanut esimerkiksi:
Mukautettujen oletusvalintojen määrittäminen
Jos olet tottunut käyttämään esim. valintapainikkeita tai valintaruutuja Gravity Formsissa, olet luultavasti huomannut, että ne ovat täynnä valintoja, kuten "First Choice", "Second Choice", "Third Choice". Tämä on Gravity Formsin oletuskäyttäytyminen, jos valintoja ei ole tallennettu (ennen), ja tämä laukaisee vain näissä tietyissä kenttätyypeissä. Mutta mukautetun kenttätyypin kohdalla valintoja ei täytetä. Tämä tekee siitä hieman hankalia, koska et saa "+" -painiketta lisätäksesi toista vaihtoehtoa. Sinun on käytettävä "Joukkolisäys / ennalta määritetyt valinnat" -painiketta, lisättävä siihen joitain vaihtoehtoja, ja sen jälkeen pääset käyttämään "+" -painikkeita vaihtoehtojen lisäämiseksi. Mutta on helppo määrittää joitain mukautettuja valintoja – sinun tarvitsee vain määrittää luokkataulukkomuuttujapublic $choicesja Gravity Forms luo automaattisesti ennalta määritettyjä valintoja kenttään, kun lisäät sen lomakkeihisi.
Huomautus: Tämä on luokkamuuttuja, jonka voit lisätä luokan yläosaan, aivan alle public $type. Jokaisen valinnan on oltava taulukko, jossa valinnan on oltava arvo avaimelle ’ text’.
public $choices = [
[ 'text' => 'Food Choice 1' ],
[ 'text' => 'Food Choice 2' ],
[ 'text' => 'Food Choice 3' ],
];
Muista, että jos olet jo lisännyt kentän lomakkeeseen, se ei täytä valintoja takautuvasti. Tämä tulee voimaan vain, kun lisäät lomakkeeseen uuden kentän.
Huomautus: Gravity Formsissa näyttää olevan mahdollista lisätä myös näppäimet ’ value’ jokaiseen valintaan. Mutta en ole saanut tätä toimimaan – arvoista tulee automaattisesti samat kuin valintateksti.
Kentän arvon määrittäminen taulukoksi
Seuraava vaihe on melko yksinkertainen, mutta välttämätön. Gravity Formsin kenttien oletusarvot ovat merkkijonoja. Arvon on oltava taulukko, koska työskentelemme useiden syötteiden kanssa. Tätä varten määrittelemme funktion is_value_submission_array()ja return true.
public function is_value_submission_array() {
return true;
}
Tämä varmistaa, että voimme työskennellä oikein useiden syötteidemme syöttämien arvojen kanssa.
Kentän tulosteen renderöiminen
Kun on kyse kentän tuotoksen renderöimisestä, on pari asiaa tiedostettava.
Ensinnäkin sinun on valittava kahdesta toiminnosta; get_field_input()tai get_field_content(). Ensimmäisessä menetelmässä Gravity Forms renderöi automaattisesti rivitysluetteloelementin, etiketin, kuvauksen ja vahvistussäiliön virheilmoituksen kenttään, ja sinä hallitset vain sisäkentän tulostetta. Toisella menetelmällä tätä ei tapahdu ja hallitset paremmin kentän tulosta. Tarra, kuvaus ja virheilmoitukset on kuitenkin hahmonnettava manuaalisesti. Ensimmäinen menetelmä, get_field_input(), on täysin hyvä useimmissa tapauksissa.
Toinen asia, joka on huomioitava, on, että kentän renderöintitoiminto vaikuttaa kolmeen eri paikkaan. Nämä kolme ovat kentän tulosteen renderöinti käyttöliittymässä, kentän esikatselu lomakeeditorissa ja lopuksi myös kenttä merkintää muokatessa. Onneksi Gravity Forms tarjoaa toimintoja, joiden avulla voit helposti määrittää, missä näkymässä olemme. Yleensä hahmonnat kentän samalla tavalla kaikissa kolmessa tapauksessa. Mutta koska suuren taulukon, jossa on paljon syötteitä, renderöinti käy tarpeettomasti kömpelölle lomakeeditorissa, olen päättänyt renderöidä kentän eri tavalla lomakeeditorissa.
Ja lopuksi meidän on varmistettava, että kaikki syötteet saavat oikean nameattribuutin, jotta Gravity Forms pystyy keräämään arvon lomakkeen lähettämisen yhteydessä. Kaikki Gravity Formsin syötteet tarvitsevat nameattribuutteja, jotka noudattavat tätä sääntöä: name="input_{FIELD_ID}"(multiselect kentät käyttävät lisätunnusta, mutta meidän ei tarvitse huolehtia siitä meidän tapauksessamme). Meillä on pääsy kenttätunnukseen, koska se on luokkamuuttuja (alkaen GF_Field). Mutta meidän tapauksessamme olemme kertoneet Gravity Formsille, että arvo on taulukko eikä yksikköarvo (edellinen vaihe), joten lisäämme hakasulkeet nimiattribuutin perään; name="input_{FIELD_ID}[]". Joten jos kentän tunnus on 4 lomakkeen sisällä, name-attribuutin tulee olla " input_4[]".
Valitsen käytön, get_field_input()jonka mukana tulee kolme parametria. Ensimmäinen parametri on lomakeobjekti, jota emme todellakaan tarvitse esimerkissämme. Toinen parametri on nykyinen arvo. Tämä voi olla joko kentän arvo, $_POSTkun lomake yritettiin lähettää, mutta se epäonnistui. Voimme säilyttää aiemmat lähetetyt arvot. Tai jos toiminto on käynnissä merkinnän muokkaamisessa, arvo on lähetyksestä tallennettu arvo. Käsittelemme arvoa tarkemmin myöhemmin. Ja kolmas parametri on syöttöobjekti, jota emme myöskään tarvitse esimerkissämme.
Aloitetaan toteuttaminen get_field_input(), joka odottaa lopullisen renderöinnin merkkijonona. Suoraan lepakkosta päätän palauttaa tyhjän merkkijonon, jos olemme lomakeeditorin sisällä – koska en halua hahmontaa koko taulukkoa tässä näkymässä. Menetelmän $this->is_form_editor()avulla voimme tarkistaa, olemmeko lomakkeen muokkauksen sisällä. Voit ohittaa tämän tai tehdä jotain muuta, jos haluat esikatselun kentästä lomakeeditorissa.
public function get_field_input($form, $value = '', $entry = null) {
if ($this->is_form_editor()) {
return '';
}
// .. Rest of code for frontend and edit entry here...
}
Seuraava vaihe on HTML-koodin rakentaminen taulukolle, joka silmukoi useita päiviä sarakkeiden ja kunkin kurssikohteen rivien luomiseksi. Mutta koska tarvitsemme pääsyn päivien joukkoon (taulukon sarakkeet) useisiin paikkoihin, meidän tulisi määrittää se luokkamuuttujaksi, jolloin se on käytettävissä kaikista sen sisällä olevista funktioista. Määritän luokkamuuttujan $delivery_days, joka sisältää joukon päiviä, joille haluan tarjota toimitusta.
class FoodDelivery extends GF_Field {
public $type = 'food_delivery';
private $delivery_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
public function get_form_editor_field_title() {
...
}
Tämä on vain esimerkki! Haluat ehkä hakea sarakkeiden taulukon jostain muualta, jota ei ole koodattu.
Palataan takaisin get_field_input()ja rakennetaan taulukko syötteillä. Ensin silmukan luokkamuuttujan yli ja luon taulukon otsikot. Sitten käyn läpi Vaihtoehdot-kenttään syötetyt vaihtoehdot. Tämä on käytettävissä luokkamuuttujasta (alkaen GF_Field) $this->choices. Jokaiselle valinnalle teen syötteen oikealla nimen attribuutilla. Meillä on pääsy kentän tunnukseen GF_Fieldluokan muuttujasta $this->id.
public function get_field_input($form, $value = '', $entry = null) {
if ($this->is_form_editor()) {
return '';
}
$id = (int) $this->id;
$table = '<table class="delivery-table"><tbody><tr>';
$table .= '<th>'. __('Course', 'txtdomain'). '</th>';
foreach ($this->delivery_days as $day) {
$table .= '<th>'. $day. '</th>';
}
$table .= '</tr>';
foreach ($this->choices as $course) {
$table .= '<tr>';
$table .= '<td>'. $course['text']. '</td>';
foreach ($this->delivery_days as $day) {
$table .= '<td><input type="number" size="1" name="input_'. $id. '[]" /></td>';
}
$table .= '</tr>';
}
$table .= '</tbody></table>';
return $table;
}
Kun tämä koodi on paikallaan, meidän pitäisi saada mukava taulukko renderöidään kenttätyypille käyttöliittymään! Ilmeisesti HTML on täysin sinun päätettävissäsi, tämä on vain perusesimerkki.
Jätämme tämän toiminnon toistaiseksi, mutta palaamme siihen myöhemmin käsittelemään lähetettyä arvoa!
Säilytä arvo oikein
Tällä hetkellä Gravity Forms tallentaa kenttämme yksiulotteisena taulukkona, joka on täytetty syötetyillä arvoilla ja tyhjillä merkkijonoilla, joissa syöte oli tyhjä. Ei ole tietoa siitä, mille päivälle tai valinnalle arvo kuuluu, paitsi indeksin. Meidän on muutettava tämä yksiulotteinen taulukko moniulotteiseksi assosiatiiviseksi taulukoksi, johon tallennamme päivän ja valintamerkinnän. Voimme sitten helposti käyttää tallennettua numeroarvoa esim $value['Ham sandwich']['Monday'].. Tämän taulukkomuunnoksen jälkeen meidän on myös sarjoitava taulukko, jotta Gravity Forms voi tallentaa arvon oikein tietokantaan.
Meidän on muutettava tämä arvotaulukko useaan paikkaan, joten määritän tälle erillisen funktion. Funktio hyväksyy yksiulotteisen taulukon ja muuntaa sen moniulotteiseksi taulukoksi, johon on tallennettu päivien ja valintojen arvot:
private function translateValueArray($value) {
if (empty($value)) {
return [];
}
$table_value = [];
$counter = 0;
foreach ($this->choices as $course) {
foreach ($this->delivery_days as $day) {
$table_value[$course['text']][$day] = $value[$counter++];
}
}
return $table_value;
}
Tämä tallentaa päivien nimet ja valinnat suoraan kentän arvon sisään. Tällä tavalla valintoja voidaan muuttaa myöhemmin rikkomatta vanhoja merkintöjä.
Siirrytään nyt lähetetyn arvon tallentamista käsittelevän funktion ohittamiseen; get_value_save_entry(). Siinä on viisi parametria, mutta tarvitsemme vain ensimmäisen, joka on lähetetty arvo. Toiminnon sisällä välitämme arvon yllä olevaan mukautettuun funktioomme, sarjoimme sen palautuksen ja lopuksi palautamme uuden arvon.
public function get_value_save_entry($value, $form, $input_name, $lead_id, $lead) {
if (empty($value)) {
$value = '';
} else {
$table_value = $this->translateValueArray($value);
$value = serialize($table_value);
}
return $value;
}
Tässä vaiheessa Gravity Forms tallentaa arvomme onnistuneesti juuri haluamallamme tavalla! Kuitenkin tallennettu arvo on nyt sarjoitettu matriisi, jonka Gravity Forms iloisesti kaikuu suoraan ulos. Meidän on otettava käyttöön toimintoja muuttaaksemme sen rumasta sarjoitetusta taulukosta kauniiksi ulostuloksi missä sitä tarvitsemme.
Lähetetyn arvon näyttäminen
On kolme paikkaa, joissa meidän on muutettava kenttämme arvon tulosta; merkintöjen luettelo, katsomalla yhtä merkintää ja Gravity Formsin yhdistämistunnisteiden sisällä. Yhdistämistunnisteita käytetään yleisimmin sähköposti-ilmoituksissa. Esimerkiksi {all_fields}yhdistämistunniste, joka näyttää kaikki lähetetyt lomakkeen arvot sähköposteissa.
Koska renderöimme saman tulosteen kolmessa eri tapauksessa, on järkevää tehdä sille erillinen funktio. Olen määritellyt mukautetun funktion, joka hyväksyy arvon; sarjoittamaton moniulotteinen taulukko parametrina. Funktio rakentaa sitten HTML-koodia, joka näyttää taulukon kauniilla tavalla ja palauttaa merkkijonon. Olen valinnut sisäkkäisen <ul>luettelon, mutta voit muuttaa tulosta haluamallasi tavalla.
private function prettyListOutput($value) {
$str = '<ul>';
foreach ($value as $course => $days) {
$week = '';
foreach ($days as $day => $delivery_number) {
if (!empty($delivery_number)) {
$week .= '<li>'. $day. ': '. $delivery_number. '</li>';
}
}
// Only add week if there were any requests at all
if (!empty($week)) {
$str .= '<li><h3>'. $course. '</h3><ul class="days">'. $week. '</ul></li>';
}
}
$str .= '</ul>';
return $str;
}
Hienoa, aloitetaan ensimmäisestä: merkintöjen luettelosta: get_value_entry_list(). Voit halutessasi tulostaa koko tulosteen täällä, mutta se voi olla melko kömpelö ja pitkä luettelonäkymässä, joten olen valinnut yksinkertaisesti palauttamisen kiinteän merkkijonon, joka selittää, että käyttäjän on mentävä syöttötietoihin nähdäkseen täydellisen yleiskatsauksen.
public function get_value_entry_list($value, $entry, $field_id, $columns, $form) {
return __('Enter details to see delivery details', 'txtdomain');
}
Tämä on tietysti täysin sinun päätettävissäsi, voit valita esimerkiksi vain ensimmäisen x merkkimäärän näyttämisen.
Toinen toiminto on se, joka vaikuttaa yksittäisen merkinnän näkymään: get_value_entry_detail():
public function get_value_entry_detail($value, $currency = '', $use_text = false, $format = 'html', $media = 'screen') {
$value = maybe_unserialize($value);
if (empty($value)) {
return '';
}
$str = $this->prettyListOutput($value);
return $str;
}
Perumme taulukon sarjoituksen WordPress-funktiolla [maybe_unserialize](https://developer.wordpress.org/reference/functions/maybe_unserialize/)()ja palautamme mukautetun funktiomme merkkijonotulosteen.
Viimeinen toiminto vaikuttaa yhdistämistunnisteisiin ja varmista, että kenttämme arvo näyttää hyvältä myös sähköpostien sisällä: get_value_merge_tag().
public function get_value_merge_tag($value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br) {
return $this->prettyListOutput($value);
}
Huomaa, että meidän ei tarvitse peruuttaa tämän funktion arvoa.
Kun nämä kolme funktiota ovat paikallaan, kaikkien lähetettyjen arvojen pitäisi näyttää melko hyviltä kaikkialla! Esimerkiksi kun katselet lähetettyä merkintää:
Yksi tärkeä asia kuitenkin puuttuu! Tässä vaiheessa syötteemme eivät säilytä aiemmin lähetettyjä arvoja ja se on melko huonoa.
Varmista, että syötteemme säilyttävät aiemmin lähetetyn arvon
On pääasiassa kaksi tapausta, joissa meidän on varmistettava, että syötteet säilyttävät aiemmin lähetetyt arvot. Ensimmäinen tapaus on, kun lomakkeen lähetys epäonnistui (esimerkiksi käyttäjä unohti pakollisen kentän). Tällä hetkellä kaikki syötteemme menettävät kaikki aiemmin syötetyt arvot ja käyttäjän on syötettävä kaikki arvot uudelleen. Toiseksi, kun sivuston omistaja muokkaa merkintää, syötteitä ei täytetä lähetetyillä arvoilla – mikä tekee arvojen muokkaamisen melko mahdottomaksi.
Korjataksemme tämän palaamme funktioon get_field_input(). Tämän funktion toinen parametri on arvo. Muista kuitenkin, että tämä toiminto vaikuttaa sekä käyttöliittymän renderöintiin että merkinnän muokkaukseen. Tämä on tärkeää, koska tallennettu arvo on erilainen näissä kahdessa tapauksessa. Jos olemme käyttöliittymässä ja käsittelemme lomakkeiden lähetystä, arvo on aiemmin mainitun yksiulotteisen taulukon muodossa. Ja jos muokkaamme merkintää, arvo on sarjamuotoisen moniulotteisen taulukon muodossa. Joten meidän on käännettävä annettu arvo oikein, jotta pääsemme get_field_input()helposti todellisiin arvoihin.
public function get_field_input($form, $value = '', $entry = null) {
if ($this->is_form_editor()) {
return '';
}
$id = (int) $this->id;
if ($this->is_entry_detail()) {
$table_value = maybe_unserialize($value);
} else {
$table_value = $this->translateValueArray($value);
}
$table = '<table class="delivery-table"><tbody><tr>';
...
}
Yllä olevassa koodissa, ennen kuin alamme luoda HTML-koodia kentän tulosteelle, luomme muuttujan $table_value, joka sisältää oikein käännetyn arvon. Käytämme GF_Fieldtoimintoa is_entry_detail()tarkistaaksemme, muokkaammeko merkintää vai emme. Ja sitten syötteillemme on helppo päästä käsiksi oikeisiin arvoihin ja asettaa ne syötteiden valueattribuutteiksi:
...
foreach ($this->delivery_days as $day) {
$table .= '<td><input type="number" size="1" name="input_'. $id. '[]" value="'. $table_value[$course['text']][$day]. '" /></td>';
}
...
Kun yllä oleva päivitys on tehty, get_field_input()kaikki mukautetut syötteemme tulisi aina täyttää edellisellä arvolla; ei ole väliä, onko kyseessä merkinnän muokkaaminen vai lomakkeen lähettämisen uudelleenyritys.
Tässä vaiheessa kaikki arvojen renderöimisestä ja tallentamisesta on tehty ja toimii täysin. Mutta on vielä yksi asia, joka meidän on ehdottomasti korjattava.
Tee kenttäpassistamme "pakollinen" vahvistus
Gravity Forms tarkistaa, onko kentän arvo tyhjä vai ei. Tämä on usein tarpeen, kun kenttä on asetettu vaaditulla tavalla. Kun kenttä on pakollinen, et voi lähettää lomaketta, jos se on tyhjä, eikö niin? Meidän ongelmamme on, että meillä on useita syötteitä ja haluamme antaa joidenkin niistä olla tyhjiä. Tästä tulee ongelma, jos kenttämme on asetettu pakolliseksi. Gravity Forms valitettavasti tulkitsee "onko tämä tyhjä" väärin ja vaatii, että kaikki syötteet on täytettävä. Joten meidän on lisättävä sääntö, joka sanoo, että jos ainakin yksi monista syötteistämme on täytetty, kentän kokonaisarvo ei ole tyhjä.
Viimeinen funktio, joka meidän on ohitettava luokassamme, on is_value_submission_empty(). Saamme vain lomakkeen tunnuksen parametrina tälle funktiolle, joten meidän on poimittava kentän arvo Gravity Forms -funktiolla sen hakemiseksi $_POSTtaulukosta: rgpost('input_<FIELD ID>'). Palautuksen pitäisi olla yksiulotteinen taulukko, jonka olemme nähneet aiemmin. Meidän tarvitsee vain käydä läpi taulukon ja palata false, jos löydämme arvon jostain. Muussa tapauksessa palaamme true, koska kentän arvo on todellakin täysin tyhjä.
public function is_value_submission_empty($form_id) {
$value = rgpost('input_'. $this->id);
foreach ($value as $input) {
if (strlen(trim($input)) > 0) {
return false;
}
}
return true;
}
Kun yllä oleva toiminto on käytössä, kenttämme ei epäonnistu lähettämisessä, jos se on asetettu pakolliseksi ja vähintään yksi syöte on täytetty.
Johtopäätös ja lopullinen koodi
Tämä opetusohjelma on osoittanut sinulle yksityiskohtaisesti, kuinka voit luoda oman mukautetun edistyneen kenttätyypin Gravity Formsille. Vaikka projektisi on erilainen kuin esimerkkini, toivon, että sinulla on vinkkejä ja a-ha:ta matkan varrella. Minusta Gravity Forms -dokumentaatio on joissain tapauksissa melko puutteellinen, ja tämä on monien yrityksen ja erehdyksen tulos! Joka tapauksessa, toivottavasti tästä on ollut sinulle hyötyä!
Viitteeksi tässä on täydellinen koodi kokonaisuudessaan:
if (class_exists('GF_Field')) {
class FoodDelivery extends GF_Field {
public $type = 'food_delivery';
public $choices = [
[ 'text' => 'Food Choice 1' ],
[ 'text' => 'Food Choice 2' ],
[ 'text' => 'Food Choice 3' ],
];
private $delivery_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
public function get_form_editor_field_title() {
return esc_attr__('Food Delivery', 'txtdomain');
}
public function get_form_editor_button() {
return [
'group' => 'advanced_fields',
'text' => $this->get_form_editor_field_title(),
];
}
public function get_form_editor_field_settings() {
return [
'label_setting',
'choices_setting',
'description_setting',
'rules_setting',
'error_message_setting',
'css_class_setting',
'conditional_logic_field_setting',
];
}
public function is_value_submission_array() {
return true;
}
public function get_field_input($form, $value = '', $entry = null) {
if ($this->is_form_editor()) {
return '';
}
$id = (int) $this->id;
if ($this->is_entry_detail()) {
$table_value = maybe_unserialize($value);
} else {
$table_value = $this->translateValueArray($value);
}
$table = '<table class="delivery-table"><tbody><tr>';
$table .= '<th>'. __('Course', 'txtdomain'). '</th>';
foreach ($this->delivery_days as $day) {
$table .= '<th>'. $day. '</th>';
}
$table .= '</tr>';
foreach ($this->choices as $course) {
$table .= '<tr>';
$table .= '<td>'. $course['text']. '</td>';
foreach ($this->delivery_days as $day) {
$table .= '<td><input type="number" size="1" name="input_'. $id. '[]" value="'. $table_value[$course['text']][$day]. '" /></td>';
}
$table .= '</tr>';
}
$table .= '</tbody></table>';
return $table;
}
private function translateValueArray($value) {
if (empty($value)) {
return [];
}
$table_value = [];
$counter = 0;
foreach ($this->choices as $course) {
foreach ($this->delivery_days as $day) {
$table_value[$course['text']][$day] = $value[$counter++];
}
}
return $table_value;
}
public function get_value_save_entry($value, $form, $input_name, $lead_id, $lead) {
if (empty($value)) {
$value = '';
} else {
$table_value = $this->translateValueArray($value);
$value = serialize($table_value);
}
return $value;
}
private function prettyListOutput($value) {
$str = '<ul>';
foreach ($value as $course => $days) {
$week = '';
foreach ($days as $day => $delivery_number) {
if (!empty($delivery_number)) {
$week .= '<li>'. $day. ': '. $delivery_number. '</li>';
}
}
// Only add week if there were any requests at all
if (!empty($week)) {
$str .= '<li><h3>'. $course. '</h3><ul class="days">'. $week. '</ul></li>';
}
}
$str .= '</ul>';
return $str;
}
public function get_value_entry_list($value, $entry, $field_id, $columns, $form) {
return __('Enter details to see delivery details', 'txtdomain');
}
public function get_value_entry_detail($value, $currency = '', $use_text = false, $format = 'html', $media = 'screen') {
$value = maybe_unserialize($value);
if (empty($value)) {
return $value;
}
$str = $this->prettyListOutput($value);
return $str;
}
public function get_value_merge_tag($value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br) {
return $this->prettyListOutput($value);
}
public function is_value_submission_empty($form_id) {
$value = rgpost('input_'. $this->id);
foreach ($value as $input) {
if (strlen(trim($input)) > 0) {
return false;
}
}
return true;
}
}
GF_Fields::register(new FoodDelivery());
}



