Closed evdinursan closed 7 years ago
Hi, there is no such an information injected to the methods.
The simplest solution would be to pass the field name to the method, e.g.
[AssertThat("Method('SomeField')")]
...
ea.addMethod('Method', function(name) {
var field = $(':input[name="' + name+ '"]')
...
});
Is it acceptable workaround?
Hi,
This is was my original intention also - to pass the fieldname from the backend - the issue is a bit more complex then this and I will tell you why: I have a user-defined form which is generated at runtime based on some fields defined in the database.
So, my model for each column of this form looks like this:
public bool IsRequired { get; set; }
public string FormColumnRegexValidation { get; set; }
[RequiredIf("IsStringValueRequiredAndEmpty(StringValue, IsRequired, EncryptedFormColumnTypeId) == true")]
[AssertThat("IsStringValueRegexMatch(StringValue, FormColumnRegexValidation)")]
public string StringValue { get; set; }
[RequiredIf("IsIntValueRequiredAndEmpty(IntValue, IsRequired, EncryptedFormColumnTypeId) == true")]
public int? IntValue { get; set; }
In order to have the front-end validation working, I need to save the IsRequired and FormColumnRegexValidation (among others) as hidden fields so the javascript validation methods recognize them and be able to use them; my ideal situation from which I started this thread, was to save these 2 (and others) properties as data-x attributes on the input field and in the validation methods to use them to check for the validity.
Being a run-time generated form, I'm not able to send from the backend the field name in order to use it on the front-end and this is why I was looking for a way to "catch" a reference to the input field.
I hope I was much clear this time.
Many thanks for your wonderful work!!!
Evdin
You could fork the repo and proceed with the following changes of the expressive.annotations.validate.js script (new lines are denoted by // (1-5) <<---- !
comment):
currentElement
variable to store the element for which expression is being computed:
(function($, window) {
'use strict';
var
backup = window.ea, // map over the ea in case of overwrite
buffer = window.console,
currentElement, // (1) <<---- !
computeAssertThat = function(method, value, element, params) {
currentElement = element; // (2) <<---- !
...
computeRequiredIf = function(method, value, element, params) { currentElement = element; // (3) <<---- !
* modify the add method - inject `currentElement` as a last argument:
toolchain = { methods: {}, addMethod: function(name, func) { // add multiple function signatures to methods object (methods overloading, based only on numbers of arguments) var old = this.methods[name]; this.methods[name] = function() { if (func.length === arguments.length) { [].push.call(arguments, currentElement); // (4) <<---- ! return func.apply(this, arguments); } if (typeof old === 'function') { return old.apply(this, arguments); } [].push.call(arguments, currentElement); // (5) <<---- ! return func.apply(this, arguments); // no exact signature match, most likely variable number of arguments is accepted }; },
When done you should be able to access the current element given as a last argument inside each method:
ea.addMethod('Method', function(arg1, arg2) { var element = arguments[arguments.length - 1]; ... });
I've not tested it, it's just an ad-hoc idea. Give it a try please.
MANY THANKS!!!!
I will try it and let you know!
Again, thank you!
Evdin
Hi, Have you found some spare time to check whether it behaves as expected? If yes, do you think it is beneficial to have such a feature (or something similar) built-in into EA e.g. as a configurable option?
Thanks.
Hi,
Sorry - didn't had the time to do it yet but most probably I will take care of it this week because I really need it.
On the other hand - I don't see why it should be configurable - it should be there - if you need it, you can just use it :-)
Thank you again and sorry for the delay.
Due to no response I've provided different implementation (see https://github.com/jwaliszko/ExpressiveAnnotations/commit/4f04d08f633e29d2eacc483c3b1d2fb6ce62601f), i.e. the current element can be now accessed through the __meta__
property of this
scope, e.g
<script>
ea.addMethod('Method', function() {
var elem = this.__meta__.element;
...
});
I think it is more straightforward than the solution presented earlier in this thread. __meta__
is a restricted identifier which is used to associate additional information with the model context. It is created to minimize eventual naming conflicts. Nevertheless it must be unique, so usage of the same name for e.g. fields names is forbidden, and enforced by relevant exception.
Any news on when this will be released? I found a need for this feature and found that it is not in the currently released nuget package.
Thanks
Hello,
In order to write a custom RequiredIf client-side method, I need a way to access the current control (input) on which the validator has been triggered.
The reason behind my question is pretty simple - instead of saving a value into a hidden field, I would like to set it as data-x custom attribute on the control level.
Can you please tell me how can I do this?
Thank you