Jump to content

Juergen

Members
  • Posts

    1,306
  • Joined

  • Last visited

  • Days Won

    13

Everything posted by Juergen

  1. Hello @marie.mdna You are right, it does not work inside url segments. The failure is inside the form action attribute and/or the redirects which does not recognize the segments after the url, so every redirect leads to the base url instead of the base url including the segments. I try to fix this now!
  2. Hello @marie.mdna It seems that there is an Ajax problem in the JS file. As far as I can see, you have an older version installed (2.2.2). Please update FrontendForms and FrontendLoginRegister to the latest version, but I recommend you to make a backup first (just for the case) and try it again. I can remember that I have also updated the JS file since 2.2.2. Please give me a short info, if the problem persists after the update. Glad to hear that you like it ?!
  3. Hello @marie.mdna Just to clearify: It happens not on pages created by the FrontendLoginRegister module, but it happens on pages that you have created for the user profile. The template of this pages allows url segments and a form which is on such a page cannot get submitted. In other words if a form is on a page which contains an url segment, than the form cannot be submitted successfully. What means "not successfully" exactly in this case? Does the form output error messages, or is there a PHP error. Please specify the problem a little bit more precious. Thanks
  4. @HMCB I guess the new feature is exactly what you are looking for ? Every rule that has been added to an inputfield is only active if the field is visible. If the field is hidden every rule added to this field is disabled. For example: You have an input field that is hidden by default and you have added the required rule. As long as the field is hidden, the required rule is inactive. If the field is visible, than the required rule will be checked during the form validation.
  5. Version 2.2.5 is out! It includes 2 bug fixes and 1 new feature: Inputfield dependencies! Most of you will know Inputfield dependencies from the ProcessWire backend. This is the same feature for FrontendForms, but it relies on a different code than the one used in the backend. I have found an interesting script on Github written by Ali Khallad and I have implemented it into FrontendForms. If you are interested in: Here is the the code on Github. Short description of Inputfield dependencies: Let's say you have two fields in your form: a number input field (field 1) and a text input field (field 2). Field 2 should only be visible if the value "1" is selected inside field 1. Otherwise, field 2 should be hidden. The input field dependencies allow you to add the condition directly to field 2 without having to write a line of JavaScript. $field2->showIf([ 'name' => 'field1', 'operator' => 'is', 'value' => '1' ]); Here is an example in action: I have written a very detailed documentation and added a lot of examples. You will find all about the new feature here. As always: This is a brandnew feature, so keep an eye if everything works as expected. Report issues or suggestions here or directly on Github. Before using it on live sites make a backup.? Jürgen
  6. Hello @marie.mdna Here is the code that should make what you want: $form = new \FrontendForms\Form('myform'); $form->setSuccessMsg('<div class="success"><h2>Everything is fine</h2></div>'); // some more inputs ...... $file = new \FrontendForms\InputFile('fileupload'); $file->showClearLink(true); // show an link to empty the input field under the input field $file->setLabel($page->p_title); $file->setDescription('<span>'.$page->p_upload_label.'</span>')->setPosition('beforeLabel'); // $file->setNotes('Description fileupload notes'); $file->setRule('allowedFileSize', '60KB'); // you can use the unit, if you want $file->setRule('allowedFileExt', ['jpg','png']); $file->setRule('uniqueFilenameInDir', true); $file->setSanitizer('pageName'); // set sanitizer $form->add($file); $button = new \FrontendForms\Button('submit'); $button->setAttribute('value', 'Send'); $form->add($button); if ($form->isValid()) { // save the content as page $p = new Page(); $p->template = $form->getValue('newPage'); $p->parent = wire('pages')->get('template=parent'); $p->title = $form->getValue('title'); if($p->save()){ $destPath = wire('config')->paths->assets.'files/'.$p->id; // the path to the destination directory foreach($form->getUploadedFiles() as $file){ wire('files')->copy($file, $destPath);// copy the file to the new folder wire('files')->unlink($file);// remove the file from the old folder } } } echo $form->render(); A little bit information about the code: First of all, add the sanitizer "pageName" to the file input field instead inside the foreach loop You can set the max filesize now using units (so instead of writing allowedFileSize('60000'), you can write allowedFileSize(60KB) which is more handy I think. This is relatively new and I have added it a few versions before - but it is not wrong if you enter the value in Bytes ?. To get all uploaded files use the getUploadedFiles() method, which outputs only the file paths of the currently uploaded files. You can use the file paths for the next steps to move the files to another directory The copy and unlink methods are PW methods and they are the best way to move files to another directory. Hope this helps!
  7. This is a good idea for an addition, but you have to keep in mind that it would probably not work for all frameworks. The problem is that not every framework has the same markup structure for inputfields. As an example would be the difference between UIKit and Boostrap: There are slightly differences in the markup, especially on checkboxes. Only changing the classnames does not work in this case. The markup rendered has to be changed too. That is the reason, why I have written the code to be able to use different render functions depending on the framework set. That is right, but do you know that you are able to change the classnames directly inside the module configuration, so the classnames will be stored inside the database? In this case the classnames will not be overwritten during an update. The main disadvantage is that you cannot use it on another installation. You will find it under "Markup and styling/Settings for markup and styling/Own CSS classes Best regards
  8. Thanks @dotnetic I will take a look at the classes. The problem is that they should not contain color classes in it - so I need to check it first.
  9. @dotnetic it would be great if you post the json file here, so I maybe include it in the next update ?
  10. Maybe the "in" validator could also be solution in your case, but to be honest, I do not know what the difference is between the "in" and the "listContains" validator.? It seems the "listContains" is for entering a list as value and the "in" for entering a single value to be compared with a list. So the "in" would probably the better choice in your case, but you need to try it out.
  11. Hello @marie.mdna glad to hear that you like it.? My idea for your scenario: You will need to load the codes from the file into an array (for example with the file_get_contents method from PHP). If you have your codes inside an array $codes = ['123456', 2849567','7899965'] you can use the built in_array check validator, which is called "listContains": $field->setRule('listContains', $codes)->setCustomMessage('Unfortunately the code you have entered is not correct.'); This validator returns true if the code that the user has entered is found inside the array and false if not. This validator is part of the Valitron library, therefore I have not described it inside my docs, but you can read more about it inside the docs of the valitron library. Tipp: Take a look at all validators, inside the docs of the Valitron library - there are a lot and they will not be explained in my docs, because they are part of Valitron, but you can use it in the same way as my custom validators. Best regards Jürgen
  12. This is the code that should work to get the desired markup: $myhiddenfield = new \FrontendForms\InputHidden('wunschliste[]'); $myhiddenfield->setAttribute(':value', 'item.id'); $prepend = '<p class="mt-5">Artikel auf deiner Wunschliste:</p> <template x-for="item in $store.cart.cart" :key="item.id" n:syntax="double" x-data> <div class="">'; $append = '</div></template>'; $myhiddenfield->prepend($prepend)->append($append); $form->add($myhiddenfield); If "$store.cart.cart" should be a PHP variable you have to adapt the code a little bit with "'".
  13. Hello @dotnetic I have found the solution for your placeholder problem. It is so simple, but I have overread it multiple times ?! For all other users: You have to name the placeholders for the label and the value as a combination of the field name + label or value. Here is an example: Your have the following field inside your form: $name = new \FrontendForms\InputText('Vorname'); $name->setLabel('Vorname'); $name->setRule('required')->setCustomMessage('Dieses Feld muss ausgefüllt werden.'); $form->add($name); The name of the field is "Vorname", which is the German word for "First name". The placeholder for the label of the field is [[VORNAMELABEL]] = name of the field + label The placeholder for the value of the field is [VORNAMEVALUE]] = name of the field + value As you can see the placeholders are always a combination of the name and the word "label" or "value". @dotnetic the mistake in your case was that you have taken the placeholder values from another example as you have written: As you can see the placeholders do not match with the names of your formfield. GENDERLABEL must be ANREDELABEL in your case because your gender field has the name attribute "Anrede" and so on. So please take care that your placeholder names match your field names. Otherwise the placeholders will not be replaced inside your mail template.?
  14. Hello @dotnetic it seems that the placeholder does not work, if you add placeholders where no appropriate formfield exists. In your case, you have set [[FIRSTNAME2LABEL]]: [[FIRSTNAME2VALUE]]<br> [[LASTNAME2LABEL]]: [[LASTNAME2VALUE]]<br> but there are no form fields with this name attribute set and this will probably stop the replacement of the placeholder with actual values. So please remove all placeholders, where no appropriate form field exist and tell me if it works. If yes I will update the function that is responsible for replacing the placeholders with values, so it will ignore those placeholders in the future. Ok that was not the reason, I have created the form code with placeholders that works. The only thing I have found was that you have set $body = $m->title; before you have initialized $m - that will not work. So please try this form. Best regards Jürgen contact-rewritten.php
  15. Ok, fine that it works on the second run ?. Sometimes something mysteriously happens and you are not able to reproduce it or trace the problem to its source. The "fl_registerpage" must be an entry inside the table "templates". If id does not longer exist, everything should be fine!?
  16. Ok, I see. You have the possibility to add markup before and after an inputfield using these methods: prepend(), append() This means you have to create the hidden input first and then you prepend (add markup before) and append (add markup afterwards to the input field) your desired markup. $myhiddenfield = new InputfieldHidden('wunschliste[]'); $myhiddenfield->setAttribute(':value', 'item.id'); $myhiddenfield->prepend("<div>")->append('</div>'); You have to replace the "div" with the markup you want to display before and afterwards. That is the only possibiltity at the moment, that could work in your case.
  17. Can you give an example of such a markup with a hidden field (HTML that should be outputted)?
  18. Hello @marie.mdna I am sorry that the module installation does not work as expected in your case. It seems that there has been something going wrong. I have installed the module on my localhost without problems. What I can say for sure, is that all the error messages that you have mentioned are caused by the missing installation of the templates. For me it seems that you had troubles during a first installation attempt, and then you have tried to install it once more. This is a typical error message if an entry with the name "fl_registerpage" is still present in the database at the moment during you have tried to install the module again. So it must have been stored during a previous attempt to install the module. This entry in the database is the "root cause" for your problem. I do not know the reason during the first module installation in your case, but you have to try to deinstall AND DELETE the module once more, to keep no orphans of the module inside the filesystem and inside the database. If the database is not "free" of FrontendLoginRegister entries, you will always get this or another error. So please try first to deinstall and delete the module the normal way. If it does not work, you have to go to directly to the database and delete the entries there. The sql error mentioned above results from an entry inside the table "templates" inside the database. Please try the deinstallation and the deletion of the module first and then download and install the module once more. Let me know if the problem persists. Do you have the possibility to go into the database (fe. with phpmyadmin)? Best regards
  19. Hello @dotnetic First of all, thanks for the detailled report and your suggestions. I am very busy at the moment, so please be patient, I will check all things that you have reported. Timeout issue: This could be possible solution. As I can rememeber, Ryan has also implemented queries for very large amounts of pages (like findMany) to prevent timeouts, but I have to dig into it a little bit more. Placeholder issue: From the first view it seems that everything is ok, but I will test it on my local installation. A few time ago, I have helped another user by a form using placeholders and it has worked as expected. (Take a look here). So for the moment I have not find a reason why it should not work, but I have to dive in a little bit deeper. File size issue: You can always disable the php ini file-size validator by setting $field->removeRule('phpIniFilesize') This removes the php.ini file-size validation, but this does not solve the wrong conversion of 10M to 100kb. I guess there is only a simple calculations issue responsible for this mistake. I will check out the function which is responsible for the conversion and I guess I can solve this problem very soon.? Only to mention: It is going very busy at the moment, so I have not the time to react within a short time and offer a solution promptly, but I will try to solve all these issues until the end of this week and give you an info here. Best regards and thanks for reporting this issues!! Jürgen
  20. Hi, here is the new code for your contact form: <?php declare(strict_types=1); namespace ProcessWire; /* * File description * * Created by Jürgen K. * https://github.com/juergenweb * File name: contactform-2.php * Created: 15.02.2023 */ $content = ''; $form = new \FrontendForms\Form('contact'); $form->setMaxAttempts(0); // disable max attempts $contacttype = new \FrontendForms\InputRadioMultiple('auswahl'); $contacttype->addOption('Einzelperson (Jahresbeitrag 50,00 EUR)<span class="asterisk">*</span>', 'Einzelperson (Jahresbeitrag 50,00 EUR)')->setAttribute('data-value', '1'); $contacttype->addOption('Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)<span class="asterisk">*</span>', 'Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)')->setAttribute('data-value', '2'); $contacttype->alignVertical(); $contacttype->setRule('required')->setCustomMessage('Bitte wählen Sie die gewünschte Mitgliedschaft aus.'); $form->add($contacttype); // add the gender field $gender = new \FrontendForms\Gender('gender'); //$gender->setLabel('Auswählen'); // so Label setzen! $form->add($gender); // add the name field $name = new \FrontendForms\Name('firstname'); $name->setRule('firstAndLastname')->setCustomFieldName('Der Vorname'); $form->add($name); // add the surname field $surname = new \FrontendForms\Surname('lastname'); $surname->setRule('firstAndLastname')->setCustomFieldName('Der Nachname'); $form->add($surname); // check if $_POST value is present for "auswahl" and set "display" according to "auswahl" value $display = 'none'; if (wire('input')->post('contact-auswahl')) { $value = explode(' ', wire('input')->post('contact-auswahl')); if ($value != 'Einzelperson') { $display = 'block'; } } // add the name2 field $name2 = new \FrontendForms\InputText('firstname2'); $name2->setLabel('Vorname (zweite Person)'); $name2->setRule('firstAndLastname')->setCustomFieldName('Der Vorname der zweiten Person'); $name2->useCustomWrapper()->setAttribute('id', 'firstname-wrapper')->setAttribute('style', 'display:' . $display); $form->add($name2); // add the surname2 field $surname2 = new \FrontendForms\InputText('lastname2'); $surname2->setLabel('Nachname (zweite Person)'); $surname2->setRule('firstAndLastname')->setCustomFieldName('Der Nachname der zweiten Person'); $surname2->useCustomWrapper()->setAttribute('id', 'lastname-wrapper')->setAttribute('style', 'display:' . $display); $form->add($surname2); // Adresse $adresse = new \FrontendForms\InputText('adresse'); $adresse->setLabel('Straße und Hausnummer'); $adresse->setRule('required')->setCustomFieldName('Die Adresse'); $form->add($adresse); // plz $plz = new \FrontendForms\InputText('plz'); $plz->setLabel('Postleitzahl'); $plz->setRule('integer')->setCustomFieldName('Die Postleitzahl'); $plz->setRule('required'); $form->add($plz); // Ort $ort = new \FrontendForms\InputText('ort'); $ort->setLabel('Ort'); $ort->setRule('required')->setCustomFieldName('Der Ort'); $form->add($ort); // add the email field $email = new \FrontendForms\Email('email'); if ($user->isLoggedIn()) { $email->setDefaultValue($user->email); } $form->add($email); // add the phone field $phone = new \FrontendForms\Phone('phone'); $phone->setLabel('Telefon / Mobil'); $phone->setRule('required')->setCustomFieldName('Die Telefonnummer'); $form->add($phone); // add the Geburtstags field $geb = new \FrontendForms\InputText('geb'); $geb->setLabel('Geburtsdatum'); $form->add($geb); $einzug = new \FrontendForms\InputCheckbox('einzug'); $einzug->setLabel('Hiermit ermächtige ich den Museumsverein Celle e.V. widerruflich, die von mir zu entrichtende Beitragszahlung jährlich bei Fälligkeit zu Lasten meines Kontos mittels Lastschrift einzuziehen. Wenn mein Konto die erforderliche Deckung nicht aufweist, besteht seitens des kontoführenden Geldinstituts keine Verpflichtung zur Einlösung.'); $einzug->setRule('required')->setCustomMessage('Bitte bestätigen Sie die Einzugsermächtigung.'); $form->add($einzug); // Kontoinhaber $kontoinhaber = new \FrontendForms\InputText('kontoinhaber'); $kontoinhaber->setLabel('Kontoinhaber'); $kontoinhaber->setRule('firstAndLastname')->setCustomFieldName('Der Name des Kontoinhabers'); $kontoinhaber->setRule('required')->setCustomMessage('Der Name des Kontoinhabers muss ausgefüllt werden.'); $form->add($kontoinhaber); // Kreditinstitut $kreditinstitut = new \FrontendForms\InputText('kreditinstitut'); $kreditinstitut->setLabel('Kreditinstitut'); $kreditinstitut->setRule('required')->setCustomFieldName('Das Kreditinstitut'); $form->add($kreditinstitut); // BIC $bic = new \FrontendForms\InputText('bic'); $bic->setLabel('BIC'); $bic->setRule('required')->setCustomFieldName('Der BIC-Code'); $form->add($bic); // IBAN $iban = new \FrontendForms\InputText('iban'); $iban->setLabel('IBAN'); $iban->setRule('required')->setCustomFieldName('Der IBAN-Code'); $form->add($iban); // add the privacy field $privacy = new \FrontendForms\Privacy('privacy'); $form->add($privacy); // add the send copy field $sendcopy = new \FrontendForms\SendCopy('sendcopy'); $form->add($sendcopy); $button = new \FrontendForms\Button('submit'); $button->setAttribute('value', 'Absenden'); $form->add($button); if ($form->isValid()) { /** You can use placeholders for the labels and the values of the form fields * This is the modern new way - only available at version 2.1.9 or higher * Big advantage: You do not have to use PHP code and there are a lot of ready-to-use placeholders containing fe the current date, the domain,..... * But it is up to you, if you want to use placeholders or do it the old way * */ $body = '[[TITLE]] [[AUSWAHLVALUE]]<br><br> [[GENDERVALUE]]<br> [[FIRSTNAMELABEL]]: [[FIRSTNAMEVALUE]]<br> [[LASTNAMELABEL]]: [[LASTNAMEVALUE]]<br>'; // check if "Doppelmitgliedschaft" has been selected - otherwise do not add these 2 fields to the mail body if (str_contains($form->getValue('auswahl'), 'Doppelmitgliedschaft')) { $body .= '[[FIRSTNAME2LABEL]]: [[FIRSTNAME2VALUE]]<br> [[LASTNAME2LABEL]]: [[LASTNAME2VALUE]]<br>'; } $body .= '[[ADRESSEVALUE]]<br> [[PLZVALUE]]&nbsp; [[ORTVALUE]]<br> [[EMAILVALUE]]<br> [[PHONELABEL]]: [[PHONEVALUE]]<br> [[GEBLABEL]]: [[GEBVALUE]]<br><br> [[KREDITINSTITUTLABEL]]: [[KREDITINSTITUTVALUE]]<br> [[KONTOINHABERLABEL]]: [[KONTOINHABERVALUE]]<br> [[BICLABEL]]: [[BICVALUE]]<br> [[IBANLABEL]]: [[IBANVALUE]]<br><br>'; // send the form with WireMail $m = wireMail(); if ($form->getValue('sendcopy')) { // send copy to sender $m->to($form->getValue('email')); } $m->to('mail@mail.de')// please change this email address to your own ->from($form->getValue('email')) ->subject('Ein neuer Mitgliedsantrag von ' . $form->getValue('firstname') . ' ' . $form->getValue('lastname')) ->title('<h1>Neuer Mitgliedsantrag</h1>') // this is a new property from this module ->bodyHTML($body) ->sendAttachments($form); if (!$m->send()) { $form->generateEmailSentErrorAlert(); // generates an error message if something went wrong during the sending process } } $content .= $form->render(); echo $content; I have added some additional validation rules to certain fields, some data attributes for the Javascript and some custom labels. Please replace this code with yours (but backup your code first ? ). To show/hide that name fields for the second person, you will need this little JavaScript snippet. <script> let auswahl = document.getElementsByName("contact-auswahl"); if(auswahl.length){ // add event listener to these radio buttons auswahl.forEach(function(elem) { elem.addEventListener("click", function() { let selected = elem.getAttribute('data-value'); let firstname = document.getElementById('firstname-wrapper'); let lastname = document.getElementById('lastname-wrapper'); if(selected == '2'){ firstname.style.display = 'block'; lastname.style.display = 'block'; } else { // hide the fields firstname.style.display = 'none'; lastname.style.display = 'none'; } }); }); } </script> Please add it to your template (fe before the closing body tag). That is all -> the form should work as expected. So please try it out. What I have not done is to make the name fields of the second name required if "Doppelmitgliedschaft" has been selected. It does not work with the "requiredWith" validator. So for this usecase a new validator has to be developed. Maybe I will try to develop this new validator and add it to the next update. Best regards
  21. You do not need Ajax in this case - only JS is enough. I will try to write the JS for showing and hiding the fields and afterwards we will see further for setting the fields to required or not.? Thanks! I know these docs are just like more a book, so offering examples is often much clearer for the users.
  22. Ok, I will try to figure it out. I guess these 2 fields should be required if "Doppelmitgliedschaft" is selected, am I right?
  23. Ok, I see! Just to mention: To validate the form (including the hidden fields if they are displayed after clicking a certain radio button) all fields must be added to the form object. This means: You need to create ALL form fields first and add them to the form object (independent if the should be visible or not). Now all fields are visible. This is the point were you are now. To change the visibility of certain form fields, you need Javascript (Jquery or plain JS). Take an eventlistener and check if radio button 1 (Einzelperson) or radio button 2 (Doppelmitgliedschaft) has been clicked. Depending on that you hide or show the fields inside the form. The second part would be the validation depending on the radio button status. So you need to add a validator which has a dependency on the radio button value selected. To clearify: If you want to make some of the fields required, if they are visible, you need to add a required validator with dependency of the value selected in the radio button multiple. More in detail: Field A is only required if radio button A is selected, Field B is only required if radio button B is selected and so on. So we need a kind of "requiredIf" validator, but I am afraid that Valitron does not offer such a validator. There is only a requiredWith validator and I guess this is not the right one for your usecase, but I have not used it before, so I am not sure Maybe there is a need to create a custom validator for this scenario.? That does not matter - I am speaking German ? Can you post the complete form code here, so I can make an exact copy of your form on my local host for testing purposes. Please also write which form fields should be visible on the first and wich one on the second radio button.
  24. Hello @mjut Just to clearify: You have created a form and inside this form there is a radio multiple inputfield with, lets say 3 radio buttons (A,B,C). If the user clicks on radio button A, then some form fields will be displayed (added) to the form. If the user clicks on radio button B, then other form fields will be displayed (added). At the end the user submits the form and it should be validated. Is this the correct scenario that you want to achive? Can you post the form code, that you have so far?
  25. Version 2.2.0 is out! This version is a bigger update, so I have decided to change the version number from 2.1.xx to 2.2. Whats new? This version includes a new admin module called "FrontendForms Manager", which is an easy to use UI for entering as many questions as you want for the "Simple question CAPTCHA". At the moment this module is only for entering questions, but I have plans for the future to expand the functionality. That is the reason why I do not call it only "Question Manager" or something like that. The "Simple question CAPTCHA" is a CAPTCHA type that I have added not so long ago and it forces the user to answer a simple question before submitting the form. You will find a live example using this new module with the simple question CAPTCHA here: https://www.schulfreund.at/kontakt/ Unfortunately, this page is only in German, but you will get the idea how it works ? I have not so much real life experience with this CAPTCHA type, but @Andi from the forum uses this type of CAPTCHA very heavily and he had no problems with SPAM until now. So if you have troubles with SPAM, give this CAPTCHA type a chance to be your friend ?! The only disadvantage of this CAPTCHA type is, that you have to create your questions first. But the big advantage is that you can adopt the questions to your customer, so that the CAPTCHA has a more personal touch. The usage of this module is optional, so it will not be installed automatically during the update. You will need to got the module manager and install it like all other modules. I do not want to go to much into detail, because I have written a description of the FrontendForms Manager in the Readme file on Github. There you can find also more images about the Userinterface. So take a look there to get more information about it. Here is only a brief description about the funcionality of this module: Creates a new admin page under Setup called "FrontendForms Manager" After clicking the link you will be redirected to the "Dashboard" The Dashboard page contains some statistical data about the questions and a little statistical section with charts By clicking on a button on the "Dashboard page" you will be redirected to the next page which contains all questions inside a table (a kind of questions overview page) There you can select if you want to edit/delete or to add a new question Depending on your choice you will be redirected to an "edit" or "add new" page where you can enter the several data for the question Each question is highly customizable, which means that you can enter notes, description, error message, success message etc. individually for each question As always, this is a brand new module, so it is not recommended to try it out on a live site first. I have run several tests without problems, but I cannot cover all possible scenarios. If you discover any problems, please report it here or directly on GitHub. Special thanks goes to @bernhard for writing a fantastic tutorial on "How to create custom admin pages". This tutorial helped me a lot during the development of this module. Jürgen
×
×
  • Create New...