Forms migration, dynamic fields & adding blocks of text
I have a few questions:
Let's say I have multiple forms that I'd like to be able to migrate from one instance of Umbraco to a different one. Are there specific files I can move to export/import the forms?
Is there any plan to implement dynamic fields in the future? I understand that it can get complicated.
If I wanted to have a block of text somewhere in the middle of the form (Like a paragraph above a group of check boxes) What would be the best way to accomplish that?
Transferring Forms. To copy forms from one environment to another (e.g., dev to prod), all you should need to do is copy the ~/App_Data/Formulate/Json folder from one file system to another. This is the default folder for the default persistence layer. You can reconfigure this path by changing the setting in persistence.config. Also, this persistence layer is entirely swappable, so you could for example implement a persistence layer that stores everything in SQL Server if you liked.
Conditional Fields. I assume you mean the ability to take various action based on some conditions (e.g., hide/show fields based on the value of another field, or populate one field based on the value of another field). That will probably happen eventually, but these scenarios are so varied that my shorter-term plan is to allow meta data to be added to forms so that developers can enable these behaviors themselves. It should already be possible to add some JavaScript to hide/show some fields based on the value of another field, if that's what you're after. It would have to be somewhat custom though, as you'd probably want to make that happen based on field aliases. Another option you could consider is to create some custom field types that allow for these conditions (e.g., "Conditional Text" could hide/show based on the value of another field that you specify as part of the configuration for that field).
Rich Text in Form. I recommend creating a custom field type. Maybe call it something like "Rich Text Field". That way, you can add it to the form and the layout like any other field type.
Let me know if you'd like some pointers or further info on any of the above items.
Also, if you want to contribute to Formulate, that would be great. Just be sure to create a ticket for what you plan to work on so I can give you the go-ahead and any guidance so the pull request will more likely be accepted.
For the "Rich Text Field" type I think I pretty much got it by making changes in the same places that were made in this commit: https://github.com/rhythmagency/formulate/commit/00c0fb2a1b732ec25c1044705ee5e9f7d8c83392 although I'm trying to figure out how the back office fields translate information to the form on the template side. For example if I wanted to just take the "label" value from the custom field in the back office and only display that in the form.
As far as conditional fields, let's say I wanted to create a checkbox custom field type that toggles the visibility of the field beneath it. Where would I write the JavaScript for that functionality?
Thanks for the help, if either of these follow-up questions don't make sense I can clarify them. Also I would love to contribute to Formulate once I have a better understanding of some of these concepts :)
That JavaScript gets compiled with some other JavaScript files into a single one, and that single one is the file you'd see on a website with Formulate installed.
For the custom field type, you'd write part of the JavaScript in the same files shown in the commit you linked for the textarea. For the frontend JavaScript that actually does the toggling on the rendered form, you'd do that in the field.js file I linked above, or in one of these:
Again, those files are combined into a single JavaScript file when the Formulate package is created.
The rich text field might be useful to incorporate into the core of Formulate. However, since I have some different ideas about how I plan to handle conditional fields, the conditional checkbox would probably be better suited as something you develop in your own project. Maybe we can even consider developing a second Formulate repo containing extra customizations like this that most people are unlikely to use but that some will find useful.
I do have one question about a "dynamic" checkbox field type, what I'm trying to do again is to have a checkbox field type that toggles hide/show on the field directly beneath it. From what I understand ngShow is a built-in directive in Angular that can be used to show and hide html elements. Would it go right into the "create[fieldname]" function on the template side of things? for example, something like:
function createToggleNextField(field) {
var container = angular.element('<div></div>');
var label = angular.element('<label class="formulate__toggle-label"></label>');
var el = angular.element('<input type="checkbox" ng-model="checked" value="1" />');
var span = angular.element('<span></span>');
span.text(field.label);
label.append(setGlobalInputAttributes(field, el, {
formControl: false,
disableAutocomplete: false
}));
label.append(span);
container.addClass('formulate__toggle');
container.append(label);
//would it be something like this?
container.next('ng-scope').attr("ng-show", "ng-hide");
return container;
Yep, you could do it a bit like that. Though, keep in mind that the attaching of the ng-show attribute in the way you are doing it may not work for a number of reasons, including:
Since the form is constructed on-demand, the "next" field may not yet exist in the DOM.
AngularJS has a compile process. Directives like ng-show need to be compiled for them to work. Note that AngularJS "compiling" does take place on the client-side. Angular does automatic compilation in most situations, but it also has the $compile service for situations when you need to manually compile things (see here). Formulate uses that here, in case you want an example.
You are assigning the ng-show attribute a value of ng-hide, which makes no sense. The value should be some expression that evaluates to true or false.
I won't be going into detail about how to accomplish exactly what you're after as it's fairly non-trivial, but thought I'd at least give you those pointers.
Forms migration, dynamic fields & adding blocks of text
I have a few questions:
~/App_Data/Formulate/Json
folder from one file system to another. This is the default folder for the default persistence layer. You can reconfigure this path by changing the setting inpersistence.config
. Also, this persistence layer is entirely swappable, so you could for example implement a persistence layer that stores everything in SQL Server if you liked.Let me know if you'd like some pointers or further info on any of the above items.
Also, if you want to contribute to Formulate, that would be great. Just be sure to create a ticket for what you plan to work on so I can give you the go-ahead and any guidance so the pull request will more likely be accepted.
For the "Rich Text Field" type I think I pretty much got it by making changes in the same places that were made in this commit: https://github.com/rhythmagency/formulate/commit/00c0fb2a1b732ec25c1044705ee5e9f7d8c83392 although I'm trying to figure out how the back office fields translate information to the form on the template side. For example if I wanted to just take the "label" value from the custom field in the back office and only display that in the form.
As far as conditional fields, let's say I wanted to create a checkbox custom field type that toggles the visibility of the field beneath it. Where would I write the JavaScript for that functionality?
Thanks for the help, if either of these follow-up questions don't make sense I can clarify them. Also I would love to contribute to Formulate once I have a better understanding of some of these concepts :)
I'll try to respond in more detail later tonight when I have some free time, but here are some quick answers in the meantime.
You can see how the textarea is rendered on the frontend here: https://github.com/rhythmagency/formulate/blob/af76b07d6e31755f32105ff502022060db31ae8e/src/formulate.app/JavaScript/FormTemplates/responsive.bootstrap.angular/directives/form/field.js#L92
That JavaScript gets compiled with some other JavaScript files into a single one, and that single one is the file you'd see on a website with Formulate installed.
This is the CSHTML that converts the form definition into JSON that is then consumed by the AngularJS to render the form: https://github.com/rhythmagency/formulate/blob/af76b07d6e31755f32105ff502022060db31ae8e/src/Website/Views/Partials/Formulate/Responsive.Bootstrap.Angular.cshtml
For the custom field type, you'd write part of the JavaScript in the same files shown in the commit you linked for the textarea. For the frontend JavaScript that actually does the toggling on the rendered form, you'd do that in the field.js file I linked above, or in one of these:
Again, those files are combined into a single JavaScript file when the Formulate package is created.
The rich text field might be useful to incorporate into the core of Formulate. However, since I have some different ideas about how I plan to handle conditional fields, the conditional checkbox would probably be better suited as something you develop in your own project. Maybe we can even consider developing a second Formulate repo containing extra customizations like this that most people are unlikely to use but that some will find useful.
FYI, I wrote an article explaining how to create custom field types: http://www.formulate.rocks/articles/custom-field-types
Let me know if you have any further questions and I'll expand the article where appropriate.
Thanks for the article, it's been very helpful.
I do have one question about a "dynamic" checkbox field type, what I'm trying to do again is to have a checkbox field type that toggles hide/show on the field directly beneath it. From what I understand ngShow is a built-in directive in Angular that can be used to show and hide html elements. Would it go right into the "create[fieldname]" function on the template side of things? for example, something like:
}
Yep, you could do it a bit like that. Though, keep in mind that the attaching of the
ng-show
attribute in the way you are doing it may not work for a number of reasons, including:ng-show
need to be compiled for them to work. Note that AngularJS "compiling" does take place on the client-side. Angular does automatic compilation in most situations, but it also has the$compile
service for situations when you need to manually compile things (see here). Formulate uses that here, in case you want an example.ng-show
attribute a value ofng-hide
, which makes no sense. The value should be some expression that evaluates to true or false.I won't be going into detail about how to accomplish exactly what you're after as it's fairly non-trivial, but thought I'd at least give you those pointers.
is working on a reply...