• Hello Fabrik Community

    Fabrik is now in the hands of the development team that brought you Fabrik for Joomla 4. We have recently transitioned the Fabrik site over to a new server and are busy trying to clean it up. We have upgraded the site to Joomla 4 and are running the latest version of Fabrik 4. We have also upgraded the Xenforo forum software to the latest version. Many of the widgets you might have been used to on the forum are no longer operational, many abandoned by the developers. We hope to bring back some of the important ones as we have time.

    Exciting times to be sure.

    The Fabrik 4.0 Official release is now available. In addition, the Fabrik codebase is now available in a public repository. See the notices about these in the announcements section

    We wish to shout out a very big Thank You to all of you who have made donations. They have really helped. But we can always use more...wink..wink..

    Also a big Thank You to those of you who have been assisting others in the forum. This takes a very big burden off of us as we work on bugs, the website and the future of Fabrik.

Toggle Submit button - alternative code?

Bauer

Well-Known Member
I've never been able to get the Toggle Submit form feature working correctly.
(And it doesn't cover the 'Apply 'button.)

First I should mention I'm using the latest versions of Fabrik and Joomla and php v.7.1.10 - with the standard bootstrap templates.

I could never figure why - but whenever I have tried using the Toggle Submit with Ajax Validation feature, the submit button was not being toggled as expected. It would not disable until the same element was edited twice. and once it disabled nothing I could do would make it enabled again - even when all of the invalid elements had obviously been fixed to pass validation tests and no red elements remained.

Over the past week I finally dove into the code in media/com_fabrik/js/form.php.
It seems like there is some pretty complex stuff going on there trying to keep track of what is valid, what needs to be validated, etc.

But from echoing values to the js console, it looks like the code was checking the validation on elements that should not have been included (ignoring the conditional php code that should have been checked to verify if the validation needed to be run or not?). That meant it was validating some hidden elements in the form which explains why I didn't see them in red.

After wondering how I could fix this and trying to figure out the difference between the variables being tracked (mustVaildate, mustValidateEls, this.hasErrors- my head spins) , on a whim, I thought - "Why is this all being done when the validation seems to work just fine otherwise - and we already know what elements didn't pass validation because they have a class that causes them to be displayed in red? "

So I tried simplifying the heck out of the code on form.php and this now works for me...

I changed the 'if' code at line 1121 inside
if (this.options.mustValidate)
(which is nested inside if (this.options.toggleSubmit) {
to just use
this.toggleSubmit(true);
JavaScript:
            if (this.options.toggleSubmit) {
                if (this.options.mustValidate) {
                    this.toggleSubmit(true);
/*                
                    if (!this.hasErrors.has(id) || !this.hasErrors.get(id)) {
                        this.mustValidateEls[id] = false;
                    }
                    if (!this.mustValidateEls.hasValue(true)) {
                        this.toggleSubmit(true);
                    }
*/                 
                }
                else {
                    this.toggleSubmit(this.hasErrors.getKeys().length === 0);
                }
            }

Then in the toggleSubmit function at the bottom of the file (line 2507) I changed the code to ignore the 'on' (true/false) parameter passed to it and use this code instead - which basically counts the number of divs with the 'error' class and uses that to set the logical value of 'on' - which is then used to toggle the Submit (and Apply) button.

I also added a 'not-allowed' cursor to make it more obvious - and just use the title attribute to provide tip text.
JavaScript:
        toggleSubmit: function (on) {
            var submit = this._getButton('Submit');
            var apply = this._getButton('apply');
            var errcount = jQuery("#"+jQuery(this.form)['0'].id).find("div.error").length;
            on = (errcount == 0);
            if (typeOf(submit) !== 'null') {
                if (on === true) {
                    submit.disabled = '';
                    submit.setStyle('cursor', 'pointer');
                    submit.setStyle('opacity', 1);
                    submit.setAttribute('title', 'Submit Form');                 
                }
                else {
                    submit.disabled = 'disabled';
                    submit.setStyle('cursor', 'not-allowed');
                    submit.setStyle('opacity', 0.5);
                    submit.setAttribute('title', 'Form cannot be saved until all inputs have been validated');                 
                }
            }
            if (typeOf(apply) !== 'null') {
                if (on === true) {
                    apply.disabled = '';
                    apply.setStyle('cursor', 'pointer');
                    apply.setStyle('opacity', 1);
                    apply.setAttribute('title', 'apply Form');                 
                }
                else {
                    apply.disabled = 'disabled';
                    apply.setStyle('cursor', 'not-allowed');
                    apply.setStyle('opacity', 0.5);
                    apply.setAttribute('title', 'Form cannot be applied until all inputs have been validated');                
                }
            }
            Fabrik.fireEvent('fabrik.form.togglesubmit', [this, on]);
        }
You may notice I removed the check for fabrikSubmitWrapper - because that didn't work anyhow.
(And I wonder if that wrapper isn't what caused this to mess up to begin with? - i.e. some other javascript or css code not expecting that wrapper around the submit button?)
That goes back to this thread which seem to be unresolved?
Able to use "validation" tooltip for disabled submit button?

This is probably an oversimplification and there's something I'm missing here - which is why I didn't even try adding to github. But for now it works for me - and any and all feedback is welcome.:D
 
Last edited:
I think the thing you are missing is the difference between "Toggle submit" and "Must Validate". The latter says "this validation MUST BE RUN". In other words, the user must specifically set this element and trigger a validation. This was added as a specific requirement for a client, and isn't generally useful for most people.

Toggle submit just says "don't enable the Submit button if any validations have failed". Which yes, is waaaay easier, and the way you did it would work. But the code as-is has to handle figuring out which elements are flagged as "must validate", and making sure those validations are specifically run.

I suspect your problem is simply that you are setting "Must validate" on elements. Which you almost certainly don't need, if all you care about is not enabling the Submit button if there are any validation failures.

The fabrikSubmitWrapper was a very frustrating attempt to change the tooltip on the submit button to say "This won't be enabled while there are failed validations on the form". Which, it turns out, was remarkably difficult, and I gave up, I'll take another look at that one day.

-- hugh
 
I think I get what you're saying.
And I definitely want the 'Must Validate' option on these 2 elements because the options only show when new.
Because when saved, the user gets put into another usergroup - which then makes these 2 elements read-only in subsequent edits.
So it's very important that these 2 elements are entered correctly and validated when the form is new.

But I'm pretty sure that what is happening is that there are other elements that are being validated that really shouldn't be worried about (when new). And even though the validation is correct (if this 'Must Validate' feature was turned off) , the disabling of the submit button is happening, because for some reason this code that determines if the submit button should be disabled is not honoring the 'Condition' set in the Validation configuration for the other elements. (I.e. Any element that has a published validation set as 'Must Validate' is being checked against 'Must Validate' even though the 'Condition' returns that it doesn't need to be validated when new (...and it isn't even visible to the user at that time).

I saw all that by echoing the names of each element to the js debug console as each 'Must Validate' element was being checked.
 
It should be obeying the static settings, for validate "in" and "on":

https://github.com/Fabrik/fabrik/blob/master/components/com_fabrik/models/element.php#L5717

... so if shouldValidate(), which checks the in/on settings, returns false (like "in" is set to "front end" and we're on the backend, or "on" is set to "edit" and it's a new form) then we don't set the mustValidate option on the element.

However, it isn't going to take in to account any "real time" stuff like the PHP condition or whether the element is hidden or not. Although I don't think the "Condition" matters, as that's only run on the server side during actual validation, and if the Condition returns false, the validation passes. So I think your main issue would be if the element gets hidden, like by a JS event, such that the validation never gets run.

And I think the only way round that would be to add some code to the doElementFX() method, that handles that. So for events that hide/show an element or a group, check to see if any elements with mustValidate are now hidden / shown, and take some appropriate action. Which isn't entirely trivial. Probably have to maintain another array, like hiddenMustValidateEls[], and move entries between the two arrays as elements are shown and hidden. And re-run the code that figures out whether we need to enable/disable the submit button.

-- hugh
 
After updating from Github yesterday, I've got this same mess all over again.
I don't treasure the thought of having to tweak this same code every time I update from Github.:(

I tested this again just now to verify that my explanation is correct. Sure enough - what is happening is that the 'Condition' for running the validation is not being honored by the 'Must Validate' setting.

In other words, I think that the real fix is to make it so that the code first tests to verify that the 'Condition' is met before the 'Must Validate' flag is even set. And if the 'Condition' is not met, the 'Must Validate' flag should be ignored. Then I'm pretty sure everything would work as expected, no?

I just see no point in advertising this 'Must Validate' setting as a Fabrik feature when it really doesn't work correctly - or only if certain conditions are met (like no other 'conditions' in the validation).

Also, as I mentioned, if the Apply button is being used in the form configuration this code ignores it completely - so the form can always just be submitted via the apply button, regardless the 'Must Validate' setting. (That 'easy fix' is already in my code above.)
 
After updating from Github yesterday, I've got this same mess all over again.
I don't treasure the thought of having to tweak this same code every time I update from Github.:(

So learn how to use github properly. Maintain your own fork, and merge changes into it from an upstream remote. Then the only time you have to do anything other than just hit the "merge" button is if there's conflicts, where a line of code you have changed on your fork is changed in the upstream, and then all you have to do is hit "accept theirs", or "accept mine". And use a decent git-aware code editor or development environment that makes all this stuff a no-brainer.

n other words, I think that the real fix is to make it so that the code first tests to verify that the 'Condition' is met before the 'Must Validate' flag is even set. And if the 'Condition' is not met, the 'Must Validate' flag should be ignored. Then I'm pretty sure everything would work as expected, no?

As I said in a previous post, this won't work. The "Condition" is not run until the form is submitted, or an AJAX validation is run, on the server side. It's PHP code running on the server, during validation, designed to look at the state of the submitted data and decide whether to run the validation. The "Must Validate" stuff is all running in Javascript, in the browser. By definition, the JS running in the browser cannot know if the Condition is met.

I just see no point in advertising this 'Must Validate' setting as a Fabrik feature when it really doesn't work correctly - or only if certain conditions are met (like no other 'conditions' in the validation).

And I still think you totally misunderstand what Open Source code is, and what Fabrik is. It's a toolkit, that provides useful features that may or may not help with building your app. Some features get added for specific projects, that work for specific circumstances, but may not be helpful in other circumstances. But if it makes you feel happier, I'll add some language to the "Must Validate" tooltip saying "may not work as expected with validation conditions" and write it up in the wiki.

-- hugh
 
On the chance that I'm totally misunderstanding what you are getting at, explain how this would work in your suggestion:

We have two elements, radio1 and field1. You have a validation condition on field1 that returns false (don't validate) if radio1 has the value 1. The radio1 element defaults to 0.

The page loads. Radio1 is 0, so field1 is going to get validated (in your scenario, we've somehow checked that validation condition during page load). The page is now loaded, and you select radio1 option 1. How does the Javascript on the page now know that field1 is not going to be validated, so should be removed from the "must validate" list?

-- hugh
 
I didn't quite absorb all that the last time, sorry. And for that matter I totally forgot about this tweak that I made just a little over a month ago until I was about an hour into trying to figure out what the problem was after I updated. (That's just me - and part of "my condition" - so sorry for making you put up with that.)

After reviewing those 2 areas of code in form.php to be sure that the there hadn't been anything else introduced, it was just a matter of 2 minutes to cut and paste those 2 blocks of code into form.php and then copy form.php into the dist folder. And now everything works fine again. So I can handle this little tweak and will quit whining about it, I promise.:p

BTW, is there a way I can 'minify' my edits to form.php before copying it into the dist folder?

Thanks so much for setting me straight on this Hugh. I really appreciate all your help. All I know is I'm finally almost there with this project and I could never have done it if not for Fabrik - and your help.:cool::)
 
(We could make the condition more esoteric, like it checks a weather web service, and doesn't validate field1 if the temperature in Naples is > 58F)
 
No problem - just excuse my snarky responses.

BTW, is there a way I can 'minify' my edits to form.php before copying it into the dist folder?

We use a version of 'uglify', as an npm module in our Grunt scripting. But any minifier would work. There are a number of online ones, like:

https://jscompress.com

Although as with any online tool, be careful you don't get spoofed into using one that does Bad Things <tm>, and wind up inserting malicious JS into your site.

-- hugh
 
Although as with any online tool, be careful you don't get spoofed into using one that does Bad Things <tm>, and wind up inserting malicious JS into your site.

-- hugh
Thanks. My final question is, why is the world like this to begin with? I'll never understand it.:mad:
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top