✅ WEB- och WordPress -nyheter, teman, plugins. Här delar vi tips och bästa webbplatslösningar.

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

7

I den här handledningen visar jag dig hur du skapar en avancerad anpassad Gravity Forms-fälttyp. Fältet kommer att ha flera inmatningar och kommer att behöva speciell hantering för att lagra och visa de inskickade värdena.

Vad vi ska göra

I det här exemplet utgår jag från ett exempel på en WordPress-webbplatsägare som sysslar med lunchleveranser på en arbetsplats. Ägaren har ett formulär där folk kan fylla i vilken typ av lunch de vill ha och hur många för varje dag i veckan. Detta kan lösas som en tabellliknande metod för att mata in ett nummer för vilken kurs som helst på vilken dag de vill ha leverans.

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

Kurserna är redigerbara i fältets inställningar i formulärredigeraren och kan ändras när som helst. Och för varje formulärinlämning får webbplatsägaren en fullständig översikt över de inlämnade värdena:

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

Uppenbarligen är detta bara ett exempel och du måste förmodligen anpassa detta till ditt fall. Men med det här exemplet får vi en chans att lära oss hur man hanterar flera input i ett enda fält. Det borde ge dig några idéer om hur du hanterar din egen anpassade fälttyp.

Innan du börjar koda

Innan vi börjar behöver vi en plats för att lägga till vår kod. Du kan lägga till detta i ditt tema functions.phpeller din plugin-fil.

Metoden jag har valt att gå efter är objektorienterad, vilket innebär att skapa en klass som utökar Gravity Forms GF_Fieldklass. Jag rekommenderar att du lägger klassen i en separat fil i ditt projekt. Du bör också kontrollera att Gravity Forms plugin finns innan du inkluderar din klass för att förhindra att din webbplats kraschar.

Om du är intresserad kan du ta en titt på Gravity Forms dokumentation på GF_Field. Du hittar fler funktioner och variabler som du kan behöva för din fälttyp.

Genom att utöka GF_Fieldklassen kan vi helt enkelt välja att åsidosätta de funktioner vi behöver ändra. När det gäller de funktioner vi inte åsidosätter, kommer Gravity Forms att köra standarden som definieras inuti GF_Field. I handledningen nedan går vi igenom varje funktion vi behöver åsidosätta för vårt anpassade fält en efter en. Utan vidare, låt oss börja!

Skapa en anpassad fälttyp

Det första steget är att definiera en anpassad PHP-klass som utökar GF_Field. Ge klassen ett unikt namn och se till att det ingår i ditt projekt. Efter klassdefinitionen kör vi den register()statiska funktionen GF_Fieldgenom att skicka en instans av vår klass som parameter. Detta initierar vår klass och registrerar fälttypen.

Den enda obligatoriska variabeln du behöver i din klass är $type. Klassvariabeln $typemåste vara unik och är ett snigelnamn för din fälttyp. I mitt exempel har jag döpt det till ‘ 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()); }

Med denna lilla kodbit bör vår anpassade fälttyp läggas till som ett tillgängligt val i Gravity Forms-redigeraren. Som standard visas den i slutet av "Standardfält"-rutan. Eftersom vi inte har gett vårt fält ett rätt namn än (det är nästa steg), är knappen märkt som värdet på $type.

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

Definiera fältets namn

Nästa steg är lätt; helt enkelt ge vårt område ett bättre namn. För att göra det åsidosätter vi funktionen get_form_editor_field_title(). Allt vi behöver göra är att returnera en sträng med fältets namn.

public function get_form_editor_field_title() { return esc_attr__('Food Delivery', 'txtdomain'); }

Med denna funktion i vår klass uppdateras knappen för att lägga till fältet med en mycket bättre etikett.

Ändra fältkategori

Detta steg är valfritt. Som standard visas vår anpassade fälttyp i rutan "Standardfält", men vi kan ändra det. Låt oss anta att vi vill att det ska visas i rutan "Avancerade fält" istället.

För att ändra kategorin vi vill att fältet ska visas i åsidosätter vi funktionen get_form_editor_button(). Vi måste returnera en associativ array med två element. Som värde till nyckeln ‘ group‘ anger du det interna namnet på kategorin du vill att knappen ska visas i. Tillgängliga alternativ här är ‘ standard_fields‘, ‘ advanced_fields‘, ‘ post_fields‘ eller ‘ pricing_fields‘. (Du kan också skapa din egen kategori, men det tas inte upp här). Det andra elementet i arrayen behöver nyckeln ‘ text‘ och för det returnerar vi helt enkelt fältets namn genom att anropa get_form_editor_field_title(). Det här är funktionen vi just skapat ovan.

Nu flyttas knappen för att lägga till vår anpassade fälttyp till rutan "Avancerade fält".

Aktiverar fältinställningar

Om du har försökt lägga till fälttypen i ett formulär kanske du har märkt att det inte finns några inställningar alls. Du kan inte ens redigera etiketten. Sättet detta fungerar är att alla typer av inställningar faktiskt finns där, de är helt enkelt alla dolda med CSS av Gravity Forms. Vi måste definiera individuellt vilka inställningar vi vill aktivera, och Gravity Forms visar sedan de valda inställningarna åt oss.

Vi måste definiera funktionen get_form_editor_field_settings()och returnera en uppsättning av alla inställningar som vi inte vill dölja för vår fälttyp. Vilka inställningar du vill lägga till är helt upp till dig och ditt projekt. Tänk på att ditt fält ska stödja vilka inställningar du än aktiverar, annars är det meningslöst att visa en inställning för det.

Jag har skapat en snabb översikt över inställningarnas namn nedan. Detta är långt ifrån en komplett lista – eftersom det finns många inställningar som i stort sett bara är användbara för mycket specifika fälttyper. Till exempel telefonformat, datum/tidsformat och en hel massa inställningar som är relaterade till Postfält och Prisfält.

Fliken Allmänt

  • Fältetikett:label_setting
  • Fältbeskrivning:description_setting
  • Alternativ:choices_setting
  • Nödvändig:rules_setting
  • Inga dubbletter:duplicate_setting
  • Aktivera kolumner:columns_setting
  • Aktivera "välj alla" val:select_all_choices_setting
  • Aktivera "annat" val:other_choice_setting

Fliken Utseende

  • Platshållare:placeholder_setting
  • Fältetikettssynlighet och beskrivningsplacering:label_placement_setting
  • Anpassat valideringsmeddelande:error_message_setting
  • Anpassad CSS-klass:css_class_setting
  • Fältstorlek:size_setting

Fliken Avancerat

  • Admin fältetikett:admin_label_setting
  • Standardvärde:default_value_setting
  • Aktivera lösenordsinmatning:password_field_setting
  • Tvinga SSL:force_ssl_field_setting
  • Synlighet:visibility_setting
  • Tillåt att fält fylls i dynamiskt:prepopulate_field_setting
  • Aktivera villkorlig logik:conditional_logic_field_setting
  • Aktivera sidvillkorlig logik:conditional_logic_page_setting

När det gäller vårt exempel är de viktigaste fältets etikett, beskrivning, val och om fältet är obligatoriskt eller inte. Vi tillåter också inställningar för CSS-klass, anpassat valideringsmeddelande och villkorlig logik.

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' ]; }

Uppdatera formulärredigeraren och du bör nu se alla valda inställningar och flikar visas i vårt fält. Alla inställningar hanteras och sparas automatiskt av Gravity Forms.

Varsågod och lägg till några objekt i listan Val så att vi har något att arbeta med. Här är vad jag har ställt in som exempel:

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

Definiera anpassade standardval

Om du är van vid att använda t.ex. radioknappar eller kryssrutor i Gravity Forms, har du förmodligen märkt att de kommer med val som "Första val", "Andra val", "Tredje val". Detta är standardbeteende från Gravity Forms om inga val har sparats (förut) och detta utlöses endast på dessa specifika fälttyper. Men för vår anpassade fälttyp kommer inga val att fyllas i. Detta gör det lite krångligt, eftersom du inte kommer att få "+"-knappen för att lägga till ett annat val. Du måste använda knappen "Lägg till/fördefinierade val i bulk", lägga till några val där, och efter det får du tillgång till "+"-knappar för att lägga till val. Men det är lätt att definiera några anpassade val – allt du behöver är att definiera en klassmatrisvariabelpublic $choicesoch Gravity Forms genererar automatiskt fördefinierade val i ditt fält när du lägger till det i dina formulär.

Obs! Detta är en klassvariabel som du kan lägga till högst upp i klassen, precis nedanför public $type. Varje val måste vara en array, med valet som värde till nyckeln ‘ text‘.

Tänk på att om du redan har lagt till fältet i formuläret kommer det inte att fylla i valen retroaktivt. Detta träder bara i kraft när du lägger till ett nytt fält i formuläret.

Notera: I Gravity Forms verkar det vara möjligt att också lägga till nycklar ‘ value‘ till varje val. Men jag har inte fått detta att fungera – värdena blir automatiskt desamma som valtexten.

Definiera fältets värde som array

Nästa steg är ganska enkelt, men nödvändigt. Som standardvärden för fält i Gravity Forms är strängar. Vi behöver värdet vara en array eftersom vi arbetar med flera ingångar. För att göra detta definierar vi funktionen is_value_submission_array()och returnerar true.

public function is_value_submission_array() { return true; }

Detta säkerställer att vi kan arbeta korrekt med det angivna värdet av våra flera ingångar.

Återge fältutdata

När det gäller att rendera fältets produktion finns det ett par saker att vara medveten om.

Först och främst är att du måste välja mellan två funktioner; get_field_input()eller get_field_content(). I den första metoden återger Gravity Forms automatiskt omslagslistelementet, etiketten, beskrivningen och behållaren för valideringsfelmeddelande till ditt fält och du kontrollerar bara det inre fältets utdata. Med den andra metoden händer inget av detta och du har mer kontroll över fältets produktion. Du måste dock rendera etiketten, beskrivningen och felmeddelandena manuellt. Den första metoden, get_field_input(), är helt ok i de flesta fall.

Det andra man bör vara medveten om är att renderingsfunktionen för fältet påverkar tre olika platser. De tre är renderingen av fältets utdata i frontend, förhandsgranskningen av fältet i formulärredigeraren och slutligen även fältet när du redigerar en post. Lyckligtvis erbjuder Gravity Forms funktioner för att enkelt avgöra vilken vy vi befinner oss på. Vanligtvis skulle du återge fältet på samma sätt i alla tre fallen. Men eftersom det blir onödigt klumpigt att rendera en stor tabell med många ingångar i formulärredigeraren, har jag valt att rendera fältet annorlunda i formulärredigeraren.

Och slutligen måste vi se till att alla inmatningar får ett korrekt nameattribut så att Gravity Forms kan samla in sitt värde när formuläret skickas in. Alla indata i Gravity Forms behöver nameattribut som följer denna regel: name="input_{FIELD_ID}"(flervalsfält använder ett extra ID, men vi behöver inte bry oss om det för vårt fall). Vi har tillgång till fält-ID eftersom det är en klassvariabel (från GF_Field). Men i vårt fall har vi sagt till Gravity Forms att värdet är en array och inte ett singularvärde (föregående steg), så vi lägger till parenteser efter namnattributet; name="input_{FIELD_ID}[]". Så om fältet har ID 4 i ett formulär, bör namnattributet vara " input_4[]".

Jag väljer att använda get_field_input()som kommer med tre parametrar. Den första parametern är formobjektet, som vi egentligen inte behöver för vårt exempel. Den andra parametern är det aktuella värdet. Detta kan antingen vara fältets värde från $_POSTnär formuläret försökte skickas in, men misslyckades. Vi kan behålla de tidigare inlämnade värdena. Eller om funktionen körs för att redigera en post, kommer värdet att vara det lagrade värdet från inlämningen. Vi kommer att hantera värdet närmare senare. Och den tredje parametern är entry-objektet, som vi inte heller behöver för vårt exempel.

Låt oss börja implementera get_field_input()som förväntar sig den slutliga renderingen som en sträng. Jag bestämmer mig direkt för att returnera en tom sträng om vi är inne i formulärredigeraren – eftersom jag inte vill rendera hela tabellen i den här vyn. Vi kan använda metoden $this->is_form_editor()för att kontrollera om vi är inne i formulärredigering eller inte. Du kan välja att hoppa över detta eller rendera något annat om du vill ha en förhandsgranskning av fältet i formulärredigeraren.

Nästa steg är att bygga HTML-koden för en tabell som löper över en rad dagar för att generera kolumnerna och raderna för varje kursobjekt. Men eftersom vi behöver tillgång till arrayen av dagar (tabellkolumner) flera platser, bör vi definiera den som en klassvariabel, vilket gör den tillgänglig från alla funktioner i den. Jag definierar en klassvariabel $delivery_daysmed en array av de dagar jag vill erbjuda leverans för.

class FoodDelivery extends GF_Field { public $type = 'food_delivery';   private $delivery_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];   public function get_form_editor_field_title() { ... }

Detta är bara ett exempel! Du kanske vill hämta arrayen för kolumnerna från någon annanstans som inte är hårdkodad.

Låt oss gå tillbaka till get_field_input()och bygga upp vår tabell med input. Först går jag över klassvariabeln och genererar tabellrubrikerna. Sedan loopar jag över de val som angetts i fältinställningen för Val. Detta är tillgängligt från klassvariabeln (från GF_Field) $this->choices. För varje val gör jag en indata med attributen för egennamn. Vi har tillgång till fältets ID från GF_Fieldklassvariabeln $this->id.

Med denna kod på plats borde vi få en snygg tabell renderad för vår fälttyp i frontend! Uppenbarligen är HTML helt upp till dig, detta är bara ett grundläggande exempel.

Vi lämnar denna funktion tills vidare, men vi återkommer till den senare för att hantera det inlämnade värdet!

Lagra värdet på rätt sätt

Från och med nu kommer Gravity Forms att spara vårt fält som en endimensionell array fylld med de inmatade värdena och tomma strängar där inmatningen var tom. Det finns ingen information om vilken dag eller val värdet tillhör, förutom indexet. Vi behöver förvandla denna endimensionella array till en multidimensionell associativ array där vi lagrar dagen och valetiketten. Vi kan då enkelt komma åt det lagrade talvärdet för $value['Ham sandwich']['Monday']t.ex. Efter denna arraytransformation behöver vi också serialisera arrayen så att Gravity Forms kan lagra värdet ordentligt i databasen.

Vi kommer att behöva transformera denna värdematris flera platser så jag kommer att definiera en separat funktion för detta. Funktionen accepterar den endimensionella arrayen och omvandlar den till en flerdimensionell array med de lagrade värdena för dagar och val:

Detta kommer att lagra dagnamnen och valen direkt i fältets värde. Att göra det på detta sätt gör det möjligt att ändra valen vid ett senare tillfälle utan att bryta de gamla posterna.

Låt oss nu övergå till att åsidosätta funktionen som hanterar lagring av det inlämnade värdet; get_value_save_entry(). Den kommer med fem parametrar men vi behöver bara den första som är det inlämnade värdet. Inuti funktionen skickar vi värdet till vår anpassade funktion ovan, serialiserar dess avkastning och returnerar slutligen det nya värdet.

Vid det här laget kommer Gravity Forms att framgångsrikt lagra våra värderingar precis som vi vill ha dem! Men det lagrade värdet är nu en serialiserad array som Gravity Forms glatt kommer att eka rakt ut. Vi måste implementera funktioner för att omvandla det från en ful seriell array till en vacker utgång varhelst vi behöver den.

Visar det inlämnade värdet

Det finns tre ställen vi behöver för att ändra produktionen av vårt fälts värde; listan över poster, titta på en enstaka post, och inom Gravity Forms sammanslagningstaggar. Merge-taggar används oftast i e-postmeddelanden. Till exempel {all_fields}är en sammanslagningstagg som visar de fullständiga inlämnade formulärvärdena i e-postmeddelanden.

Eftersom vi återger samma utdata i tre olika fall är det vettigt att skapa en separat funktion för den. Jag har definierat en anpassad funktion som accepterar värdet; den oserialiserade flerdimensionella arrayen, som parameter. Funktionen bygger sedan upp lite HTML som visar arrayen på ett vackert sätt och returnerar strängen. Jag har valt en kapslad <ul>lista, men du kan ändra utdata hur du vill.

Bra, låt oss börja med det första: listan med poster: get_value_entry_list(). Du kan välja att mata ut hela resultatet här men det kan bli ganska klumpigt och långt för listvyn, så jag har valt att helt enkelt returnera en fast sträng som förklarar att användaren måste gå in i ingångsdetaljer för att se den fullständiga översikten.

public function get_value_entry_list($value, $entry, $field_id, $columns, $form) { return __('Enter details to see delivery details', 'txtdomain'); }

Detta är naturligtvis helt upp till dig, du kan välja att bara visa det första x antalet tecken till exempel.

Den andra funktionen är den som påverkar visningen av en enskild post: get_value_entry_detail():

Vi avserialiserar helt enkelt arrayen med WordPress-funktionen [maybe_unserialize](https://developer.wordpress.org/reference/functions/maybe_unserialize/)()och returnerar strängutdata från vår anpassade funktion.

Den sista funktionen påverkar sammanslagningstaggarna och se till att vårt fälts värde ser bra ut även i e-postmeddelanden: get_value_merge_tag().

Observera att vi inte behöver avserialisera värdet i den här funktionen.

Med dessa tre funktioner på plats borde alla inskickade värden se ganska bra ut överallt! Till exempel när du visar ett inskickat bidrag:

Handledning: Skapa en avancerad fälttyp för anpassade gravitationsformulär och hur man hanterar flera inmatningsvärden

Men det saknas en viktig sak! Vid det här laget behåller inte våra indata de tidigare inlämnade värdena och det är ganska dåligt.

Få våra input att behålla det tidigare inlämnade värdet

Det finns huvudsakligen två fall där vi måste se till att indata håller de tidigare inlämnade värdena. Det första fallet är när en formulärinlämning misslyckades (till exempel användaren glömde ett obligatoriskt fält). Just nu förlorar alla våra ingångar alla tidigare inmatade värden och användaren måste mata in alla värden igen. För det andra när webbplatsägaren redigerar en post fylls inte indata med de inskickade värdena från inlämningen – vilket gör det ganska omöjligt att redigera värdena ordentligt.

För att fixa detta återgår vi till funktionen get_field_input(). Den andra parametern till denna funktion är värdet. Men kom ihåg att den här funktionen påverkar både frontend-rendering och ingångsredigering. Detta är viktigt eftersom det lagrade värdet är olika i dessa två fall. Om vi ​​är vid frontend och hanterar inlämning av formulär, är värdet i formatet av den endimensionella array som nämndes tidigare. Och om vi redigerar en post är värdet i formatet en serialiserad flerdimensionell array. Så vi måste översätta det angivna värdet på rätt sätt för get_field_input()att enkelt komma åt de faktiska värdena.

I koden ovan, innan vi börjar skapa HTML för fältutdata, skapar vi en variabel $table_valuesom innehåller det korrekt översatta värdet. Vi använder GF_Fields funktion is_entry_detail()för att kontrollera om vi redigerar en post eller inte. Och sedan för våra ingångar är det lätt att komma åt de rätta värdena och ställa in dem som ingångarnas valueattribut:

Med ovanstående uppdaterade get_field_input()ska alla våra anpassade indata alltid fyllas i med det tidigare värdet; oavsett om det är att redigera en post eller försöka igen en formulärinlämning.

Vid det här laget är allt om rendering och lagring av våra värderingar gjort och fungerar fullt ut. Men det finns en sak till som vi definitivt måste fixa.

Gör vårt fältpass "obligatoriskt" validering

Gravity Forms har kontroller för att se om ett fälts värde är tomt eller inte. Detta är ofta nödvändigt när fältet är inställt som krävs. När ett fält krävs kan du inte skicka in formuläret om det är tomt, eller hur? Problemet för oss är att vi har flera ingångar och vi vill låta några av dem vara tomma. Detta blir ett problem om vårt fält är inställt på obligatoriskt. Gravity Forms tolkar tyvärr "är det här tomt" fel, och kräver att alla inmatningar fylls i. Så vi måste lägga till en regel som säger att om minst en av våra många inmatningar är ifyllda är fältets totala värde inte tomt.

Den sista funktionen vi måste åsidosätta i vår klass är is_value_submission_empty(). Vi får bara formulär-ID som parameter till denna funktion så vi måste extrahera fältvärdet genom att använda Gravity Forms-funktionen för att hämta det från $_POSTarrayen: rgpost('input_<FIELD ID>'). Returen bör vara den endimensionella array som vi har sett tidigare. Allt vi behöver göra är att gå igenom arrayen och återvända falseom vi hittar ett värde någonstans. Annars återkommer vi truedå fältets värde verkligen är helt tomt.

Med ovanstående funktion på plats kommer vårt fält inte att misslyckas med inlämning om det är inställt på obligatoriskt och minst en inmatning är ifylld.

Slutsats och slutlig kod

Den här handledningen har visat dig i detalj hur du skapar din egen anpassade avancerade fälttyp för Gravity Forms. Även om ditt projekt är annorlunda än mitt exempel, hoppas jag att du har några tips och a-has på vägen. Jag tycker att Gravity Forms-dokumentationen är ganska bristfällig i vissa fall, och detta är resultatet av mycket försök och misstag! Hur som helst, förhoppningsvis har detta varit till någon nytta för dig!

För referens, här är den fullständiga koden i sin helhet:

Inspelningskälla: awhitepixel.com

Denna webbplats använder cookies för att förbättra din upplevelse. Vi antar att du är ok med detta, men du kan välja bort det om du vill. Jag accepterar Fler detaljer