Het is maandag 1 november. Vandaag een demo waarbij met RSForm Pro een preview pagina gemaakt wordt waarmee je een samenvatting van het ingevulde formulier kunt tonen voordat het ingezonden wordt.

RSForm Pro Preview pagina

Hieronder wordt toegelicht hoe je een preview functionaliteit aan je RSForm formulier kunt toevoegen. Dit kan handig zijn voor formulieren verdeeld over meerdere pagina's. De inzender krijgt een samenvatting in beeld alvorens op verzenden geklikt kan worden. 

Stappenplan voor implementatie van preview pagina

  • installeer RSForm Pro
  • Ga naar Joomla Administrator > Components > RSForm! Pro > RSForm! Pro Multipage example
    • bij installatie van RSForm Pro worden twee voorbeeld formulieren toegevoegd. We gebruiken de multipage example
  • Velden bewerken
    • Voeg nieuw veld toe
      • type = Pagebreak
      • name = Page3
    • Voeg nieuwe rij toe na zojuist aangemaakte PageBreak
    • Verplaats de volgende velden naar de nieuwe rij
      • Submit
      • Footer
    • Voeg nieuw veld toe
      • type = Free Text
      • name = previewForm
      • HTML = 
        <div id="previewForm">
          <h3>Header</h3>
          <dl id="previewFormHeader">
          </dl>
          <h3>Company</h3>
          <dl id="previewFormCompany">
          </dl>
          <h3>Contact</h3>
          <dl id="previewFormContact">
          </dl>
        </div>​
    • Verplaats nieuw veld naar voor het veld Submit
    • Sla de wijzigingen op
  • Javascript oproepen
    • Het is mogelijk om in RSForm je javascript te verwerken. Ik geef er de voorkeur aan om het als extern bestand in te laden. Op die manier kan ik het opnemen in mijn GitHub repository.  
    • Form Properties > Scripts > PHP Scripts > Script called on form display
    • use Joomla\CMS\HTML\HTMLHelper;
      HTMLHelper::_('script', 'rsform-preview.js', ['version' => 'auto', 'relative' => true]);
  • Script laten uitvoeren
    • Form Properties > Scripts > PHP Scripts > Script called on form display
    • $formLayout = str_replace('rsfp_changePage(','previewBeforeSubmit(',$formLayout);
  • Sla de wijzigingen op
  • Kopieer onderstaand Gist file naar jouw template js directory met de naam rsform-preview.js
    https://gist.github.com/hans2103/f1c679bc41f9033a7da966d784912dd0
// Store this script in templates/<your-template>/js/rsform-preview.js

/**
 * Create the Review Field based on array with questions
 *
 * @param formIdValue
 * @param previewPageNumber
 * @param totalPages
 * @param validateOnChangingPage
 */
function previewBeforeSubmit(formIdValue, previewPageNumber, totalPages, validateOnChangingPage) {
  /**
   * Object with items to be filled on review
   * [key] should be present as a `<dl id=[key]></dl>` in form field with name = formReview
   * [value] is an array of items that should return in the review list
   * @type {{reviewFormTrainer: string[], reviewFormPractical: string[]}}
   */
  var blocks = {
    'previewFormHeader': [
      'FullName',
      'Email'
    ],
    'previewFormCompany':
      [
        'CompanySize',
        'Position'
      ]
    ,
    'previewFormContact':
      [
        'ContactBy',
        //'ContactWhen'
      ]
  };

  if (previewPageNumber === 3) {
    for (const key in blocks) {
      if (blocks.hasOwnProperty(key)) {
        const questions = blocks[key];

        // Clean preview block
        document.getElementById(key).innerHTML = '';

        // Render Questions
        renderQuestions(key, questions);

        // Cleanup Block if empty
        cleanupEmptyBlock(key);
      }
    }
  }
  rsfp_changePage(formIdValue, previewPageNumber, totalPages, validateOnChangingPage);
}

/**
 * Check if given id is shown or not
 *
 * @param id
 * @returns {boolean}
 */
function isShown(id) {
  var sanitizedId = id.replaceAll('_', '-')
    .replaceAll('--', '-')
    .toLowerCase();
  var elem = document.querySelector('.rsform-block-' + sanitizedId);

  if (!elem) {
    return false;
  }

  return (elem.style.display !== 'none');
}

/**
 * Return the field type of given id
 *
 * @param id
 * @returns {string|boolean}
 */
function getFieldType(id) {
  var element = document.getElementById(id);
  if (!element) {
    element = document.getElementsByName(`form[${id}][]`);
    if (element.length > 0) {
      return 'checkbox';
    }

    element = document.getElementsByName(`form[${id}]`);
    if (element.length > 0) {
      return 'radio';
    }

    return false;
  }

  var tagName = element.tagName.toLowerCase();
  if (tagName !== 'input') {
    return tagName;
  }
  return element.getAttribute('type')
    .toLowerCase();
}

/**
 * Return the field label of given id
 *
 * @param id
 * @param type
 * @returns {string}
 */
function getFieldLabel(id, type = '') {
  let element = '';

// type = radio or checkbox
  if (type === 'radio' || type === 'checkbox') {
    let elementName = `form[${id}]`;

    if (type === 'checkbox') {
      elementName += '[]';
    }

    element = document.getElementsByName(elementName)[0];
  }

// type = textarea, text
  const inputTypes = ['textarea', 'text', 'file', 'email', 'number', 'select'];
  if (inputTypes.indexOf(type) >= 0) {
    element = document.getElementById(id);
  }

  if (!element) {
    return '';
  }

  return element.closest('.rsform-block').firstElementChild.textContent;
}

/**
 * Return the field value of given id
 *
 * @param id
 * @param type
 * @returns {*[]|number}
 */
function getFieldValue(id, type = '') {
  // type = radio or checkbox
  if (type === 'radio' || type === 'checkbox') {
    let i;
    let elementName = `form[${id}]`;
    let outputChoice = [];
    if (type === 'checkbox') {
      elementName += '[]';
    }

    for (i = 0; i < document.getElementsByName(elementName).length; i++) {
      if (document.getElementById(id + i).checked) {
        outputChoice.push(document.getElementById(id + i).value);
      }
    }

    return outputChoice;
  }
  
  // type = select
  if (type === 'select') {
    var outputSelect = [];
    var select = document.getElementById(id);

    outputSelect.push = select.options[select.selectedIndex].value;

    return outputSelect;
  }
  
  // type = file
  if (type === 'file') {
    var outputFile = [];
    var files = document.getElementById(id).files;

    for (var k = 0; k < files.length; k++) {
      outputFile.push(files[k].name);
    }

    return outputFile;
  }

  // type = textarea, text, email, number
  var inputTypes = ['textarea', 'text', 'email', 'number'];
  if (inputTypes.indexOf(type) >= 0) {
    var output = [];
    output.push(document.getElementById(id).value);

    return output;
  }

  return [];
}

/**
 *
 * @param id
 * @param questions
 */
function renderQuestions(id, questions) {
  questions.forEach(function (question) {
    if (isShown(question)) {
      addRow(
        getFieldLabel(question, getFieldType(question)),
        getFieldValue(question, getFieldType(question)),
        id
      );
    }
  });
}

/**
 * Hide Title and Block when the latter is empty
 *
 * @param id
 */
function cleanupEmptyBlock(id) {
  var element = document.getElementById(id);
  if (!element) {
    return;
  }

  if (element.innerHTML !== '') {
    return;
  }

  element.previousElementSibling.style.display = 'none';
  element.style.display = 'none';
}

/**
 * Add new row to definition list
 *
 * @param fieldLabel  string
 * @param fieldValues array
 * @param elementId   string
 */
function addRow(fieldLabel, fieldValues, elementId = 'reviewFormTrainer') {
  if (Array.isArray(fieldValues) && !fieldValues.length) {
    return;
  }

  var DL = document.getElementById(elementId);

  // Cleanup field Label
  fieldLabel = fieldLabel.replace('<strong class="formRequired">*</strong>', '');
  var elementDT = document.createElement('dt');
  elementDT.innerHTML = fieldLabel;
  DL.appendChild(elementDT);

  fieldValues.forEach(function (fieldValue) {
    var elementDD = document.createElement('dd');
    elementDD.innerHTML = fieldValue;
    DL.appendChild(elementDD);
  });
}

Opmerking:

Dit script houd vooralsnog geen rekening met het uitlezen van het veld kalender. Mocht je een oplossing hebben hoor ik het graag. 

Joomla! 4 Core Editor

Een presentatie van Brian Teeman over de Joomla! 4 standaard editor.... geen extra extensies meer nodig. Engelstalige presentatie van 47min.

Joomla! 4 API

Een API (Application Programming Interface) is een software interface die het mogelijk maakt dat twee applicaties met elkaar kunnen communiceren. 
Voorbeeld in de vorm van een filmpje => https://www.youtube.com/watch?v=s7wmiS2mSXY&t=73s

Normliter ben jij de persoon die in een browser een bepaalde pagina aanklikt en vervolgens netjes een pagina in beeld krijgt. Maar het is met Joomla! 4 ook mogelijk dat je een app maakt die bepaalde informatie toont dat opgehaald moet worden vanuit je Joomla website. De makers van JoomDev hebben een filmpje met tekst en uitleg gemaakt hoe je Joomla Content middels de API kunt ophalen.

Handige links voor Joomla! 4 API

Joomla! 4 vragen

Joomla! 4 administrator is nogal groot... hoe kan ik alles kleiner maken?

Net zoals voor de frontend template kun je voor de administrator template een user.css toevoegen met daarin je eigen CSS om de styling aan te passen. Pieter Jan de Vries heeft dit al voor ons gedaan. https://github.com/pjdevries/J4Atum-user-css/blob/obix-modifications/administrator/templates/atum/css/user.css

Hoe kan ik eenvoudig cache legen in Joomla! 4?

Het legen van de cache in Joomla! 4 gaat via Joomla Administrator > System > Maintenance > Cache. Het is verstandig om tijdens het bewerken van items in Joomla een apart browservenster open te houden voor deze pagina. Klik voor het openen van de Cache pagina met rechtermuisknop op de link en kies dan voor Openen in nieuw venster.

Een andere mogelijkheid is de installatie van de extensie Regular Labs CacheCleaner. De free version maakt het mogelijk dat de cache on Save automatisch geleegd wordt. Vanaf versie 8 (vandaag 1 november uitgebracht) is het mogelijk deze in te gebruiken. https://regularlabs.com/cachecleaner

Moeite met ombouwen van een template?

Overstappen van de ene naar een andere commerciële template kan natuurlijk ook. Bijvoorbeeld RSMatias van RSJoomla. https://www.rsjoomla.com/joomla-templates/rsmatias.html

Wat is de huidige stand van zaken aangaande beschikbaarheid van webshop componenten en Joomla! 4?

  • Hikashop is al klaar voor Joomla! 4
  • RSForm Pro klaar voor Joomla! 4. Handig in combinatie met ROPayments, welke ook gereed is voor Joomla! 4.
  • Virtuemart druk doende met omzetten naar Joomla! 4
  • J2Store nog niet geschikt voor Joomla! 4
  • Pro2Store in ontwikkeling voor Joomla! 4
  • PhocaCart in ontwikkeling voor Joomla! 4

Dr. Joomla

vraag: Na een update van Joomla en SP Page Builder Pro zijn de icons in het menu verdwenen. Volgens mij zit dat in een update naar FontAwesome 5. Maar kan niet vinden waar ik de icons in het menu moet updaten.

antwoord: na onderzoek van de website via de Chrome Developer Toolbar leren we dat de iconen van het menu gebruik willen maken van Font Awesome 5 Free. Dit font wordt ingeladen door het component SP Pagebuilder. De iconen zijn daarom zichtbaar op alle pagina's waar SP Pagebuilder toegepast wordt. Op de pagina's waar geen gebruik gemaakt wordt van SP Pagebuilder wordt geen Font Awesome 5 Free ingeladen. Om ervoor te zorgen dat op die pagina's ook de iconen zichtbaar zijn kun je twee dingen doen:

  1. een override maken op de css van het menu zodat er geen Font Awesome 5 Free nodig is, maar FontAwesome (versie 4.x wordt namelijk op alle pagina's van deze site ingeladen)
  2. Het css bestand voor Font Awesome 5 Free inladen op alle pagina's. Door het inladen van het css bestand toe te voegen aan de head van je template. 

Volgende keer

De volgende JUG Eindhoven is op maandag 6 december. Het onderwerp van deze meeting en de mogelijkheid tot aanmelden is terug te vinden op https://www.joomlacommunity.nl/agenda/joomla-gebruikersgroepen/eindhoven/event/611-jug040-bijeenkomst-eindhoven

Vragen voor Dr. Joomla kun je kwijt als reactie onder de aankondiging.

Reageer

1000 Resterende tekens