This is a migrated thread and some comments may be shown as answers.

Issues with validators in a template

8 Answers 73 Views
Templates
This is a migrated thread and some comments may be shown as answers.
Derek
Top achievements
Rank 1
Derek asked on 27 Feb 2017, 08:43 PM

I have the following in side an HTML page:

<!-- Template for simple search row -->
<script id="simple-search-row" type="text/x-kendo-template">
    <div class="simple-search-row">
        <input name="fieldName"
            data-role="dropdownlist"
            data-text-field="columnDisplayName"
            data-value-field="columnName"
            data-bind="
                value: field,
                source: columnsDataSource"></input>
        <span data-for="fieldName" class="k-invalid-msg"></span>
        <input name="filter"
            data-role="dropdownlist"
            data-text-field="displayName"
            data-value-field="name"
            data-bind="
                value: type,
                source: filterTypesDataSource,
                events: { change : criteriaChanged, dataBound : simpleSearchDDLDataBound }"
            style="width: 15em;"></input>
        <span data-for="filter" class="k-invalid-msg"></span>
        <input id="value-1" name="value-1" type="text"
            data-bind="
                value: values[0]"></input>
        <span data-for="value-1" class="k-invalid-msg"></span>
        <span id="value-and" style="display: none;">#: translate('between_and') #</span>
        <input id="value-2" name="value-2" type="text" style="display: none;"
            data-bind="
                value: values[1]"></input>
        <span data-for="value-2" class="k-invalid-msg"></span>
        <a href="\\\\#" data-bind="events: { click : removeSimpleSearchRow }">
            <span class="k-icon k-i-cancel"></span>
        </a>
        <a href="\\\\#" data-bind="events: { click : addSimpleSearchRow }">
            <span class="k-icon k-i-plus"></span>
        </a>
    </div>
</script>
 
<div id="simple-search-rows" class="ui relaxed grid" data-template="simple-search-row" data-bind="source: searchFilter.criteria"></div>

 

"searchFilter.criteria" is a JS array object.  And then I have a custom validator:

var simpleSearchValidator = $('#simple-search').kendoValidator({
        messages : {
            fieldname : '',
            filter : '',
            valueone : '',
            valuetwo : ''
        },
        rules: {
            fieldname : function (input) {
                if (input.is('[name|=fieldName]')) {
                    if(input.val() === ''){
                        return false;
                    }
                }
 
                return true;
            },
            filter : function (input) {
                if (input.is('[name|=filter]')) {
                    if(input.val() === ''){
                        return false;
                    }
                }
 
                return true;   
            },
            valueone : function (input) {
                if (input.is('[name|=value-1]')) {
                    let filter = input.parent().find('[name|=filter]'),
                        criteria = (filter ? filter.val() : '');
                     
                    switch(criteria){
                        case 'EQUAL_TO':
                        case 'NOT_EQUAL_TO':
                            return true;
                    }
 
                    if(input.get(0).style.display === 'none') {
                        return true;
                    }
 
                    if(input.val() === ''){
                        return false;
                    }
                }
 
                return true;   
            },
            valuetwo : function (input) {
                if (input.is('[name|=value-2]') && input.is('')) {
                    if(input.val() === ''){
                        return false;
                    }
                }
 
                return true;   
            }
        }       
    }).data('kendoValidator');

 

The issue is that the validator's .validate() is called, it correctly identifies incorrect data based on the custom rule, however if say the fieldName input field is invalid, it displays the k-invalid-msg for EVERY row, not just the single row with the invalid data.  I am guessing this is because the name attributes for each row are not unique.   I tried creating a unique id in the template:

<!-- Template for simple search row -->
<script id="simple-search-row" type="text/x-kendo-template">
    <div class="simple-search-row">
        # var uid = windows.util.genUniqueId(); #
        <input name="fieldName#= uid #"
            data-role="dropdownlist"
            data-text-field="columnDisplayName"
            data-value-field="columnName"
            data-bind="
                value: field,
                source: columnsDataSource"></input>
        ....
    </div>
</script>
 
<div id="simple-search-rows" class="ui relaxed grid" data-template="simple-search-row" data-bind="source: searchFilter.criteria"></div>

 

Unfortunately, that did not work as the uid was only created once, at the time the template was loaded, not for each row.

Is there an easy way to generate a unique form name for the input elements in each row?

8 Answers, 1 is accepted

Sort by
0
Vasil
Telerik team
answered on 01 Mar 2017, 01:55 PM
Hello Derek,

Change:
# var uid = windows.util.genUniqueId(); #
<input name="fieldName#= uid #"
To:
<input name="fieldName#: data.yourField #"
And you will get unique name for each inputs in your rows, where the "yourField" is for example the primary key of your table.

Regards,
Vasil
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Derek
Top achievements
Rank 1
answered on 01 Mar 2017, 08:46 PM

I actually already tried something similar.  However, the inline template seems to only be called once at the time the template is read/loaded, not once per row.  At your suggestions I tried:

<input name="fieldName-#: data.yourField #"

 

However, I end up with this in the final html:

<input name="fieldName-undefined"

 

I can somewhat verify this by doing the following:

    <div class="simple-search-row">
        <!-- #= JSON.stringify(data) # -->
...

 

to which I get this in the source once:

<!-- {}-->

0
Vasil
Telerik team
answered on 02 Mar 2017, 09:49 AM
Hello Derek,

Check out this example, and inspect the input elemnets on each row. They are having unique names.
http://dojo.telerik.com/aLUfO

Regards,
Vasil
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Derek
Top achievements
Rank 1
answered on 03 Mar 2017, 10:08 PM
I checked you example, and it does work, however it only provides one-way data binding.  In my template I am binding to input fields via MVVM to get two way binding.
0
Derek
Top achievements
Rank 1
answered on 06 Mar 2017, 02:09 PM

I have partially resolved this by adding a function to the view model to return a unique name and setting the form name via data binding.

<input id="value-1" type="text"
    data-bind="
        value: values[0],
        attr: { name : value1Name }"></input>

 

let criteria = {
    field: 'key',
    type: 'CONTAINS',
    values: [
        '',
        ''
    ],
    fieldName : function() {
        return 'fieldName-' + this.uid;
    },
    typeName : function() {
        return 'filter-' + this.uid;
    },
    value1Name : function() {
        return 'value-1-' + this.uid;
    },
    value2Name : function() {
        return 'value-2-' + this.uid;
    }
};

This works great for the input textboxes, but for the two dropdown lists it seems to mess up the value data binding. :-(

0
Vasil
Telerik team
answered on 07 Mar 2017, 11:00 AM
Hello Derek,

I will be glad to debug and try to provide you further assistance on this issue. But could you please provide some runnable Dojo, that fully illustrate your requirements and current implementation.

Regards,
Vasil
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Derek
Top achievements
Rank 1
answered on 07 Mar 2017, 04:37 PM

http://dojo.telerik.com/uLIDi

If your remove the ",attr: { name : fieldName }" part in the MVVM, it correctly binds.

 

 

 

0
Vasil
Telerik team
answered on 09 Mar 2017, 01:10 PM
Hello Derek,

Yes the attr binding is not supported for the DropDownList. To overcome this you may skip the assigning of name and id to the dropdown. And to make the validation work, you will need to find the element from the child collection of the parent row by index, rather than by name.

Regards,
Vasil
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Templates
Asked by
Derek
Top achievements
Rank 1
Answers by
Vasil
Telerik team
Derek
Top achievements
Rank 1
Share this question
or