Custom Popup Editor with additional fields

2 Answers 10463 Views
Grid
This question is locked. New answers and comments are not allowed.
Cyndie
Top achievements
Rank 1
Cyndie asked on 25 May 2012, 03:06 PM
Is it possible to customize the popup editor box to show fields that are not visible in the grid, but are in the datasource the grid is bound to?

ie., if my datasource returns 10 fields and I want 5 of them to be shown in the grid, can I edit all 10 fields in the popup box?

2 Answers, 1 is accepted

Sort by
0
Accepted
Alexander Valchev
Telerik team
answered on 28 May 2012, 07:48 AM
Hi Cyndie,

By default the popup editor window will show only the grid column fields, but it is possible to include additional ones through a popup template. Here is the syntax:
editable: {
    mode: "popup",
    template: kendo.template($("#popup_editor").html())
}

Please note that when you are using a custom template, you have to set up the MVVM bindings. In the attachments you will find a small example that shows the suggested approach in action.

I hope this helps.

Greetings,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Safak
Top achievements
Rank 1
commented on 12 Jun 2012, 06:01 AM

I am trying to use customized the popup editor box too. I have managed to use combobox as example above. However i couldn't put the autocomplete input.

popup_editor template:

<div class="k-edit-label"><label for="f1">F1</label></div>
<div data-container-for="f1" class="k-edit-field"><input name="f1"
                    data-bind="source: data, value: f1"
                    data-text-field="f1"
                    data-role="autocomplete" /></div>

script:

function EditorF1(container, options) {
                            $('<input name="' + options.field + '"/>')
                                .appendTo(container)
                                .kendoAutoComplete({
                                    minLength: 1,
                                    dataSource: data
                                });
                        }

can you please give me an advise?

Thank you

Raffael
Top achievements
Rank 1
commented on 20 Jul 2012, 12:37 PM

I have some problems to get this (http://www.kendoui.com/forums/ui/grid/custom-popup-editor-with-additional-fields.aspx#2124595  ) working with v2012.2.710.

Template:
<script id="fs-acl-editor" type="text/x-kendo-template">1234</script>


Code:
            $("#fs-item-data").kendoGrid({
                dataSource: dataSource,
                navigatable: true,
                columns: file_browser.getAclColumns(),
                pageable: true,
                height: 400,
                toolbar: ["create", "cancel"],
                editable: {
                    mode: "popup",
                    template: kendo.template($("#fs-acl-editor").html())
                }
            });


Result:
function anonymous(data) { var o, e = kendo.htmlEncode; with (data) { o = " 1234 "; } return o; }


Bug?



Thank you
Oleg
Top achievements
Rank 1
commented on 20 Jul 2012, 08:46 PM

I expect the same problem as Raffael. Datasource is binding to remote data.
In example, provided by Alexander Valchev everything is worked well (mayby because of localstorage using?).
Mo
Top achievements
Rank 1
commented on 21 Jul 2012, 10:23 PM

I too am having this problem. I configure the template as:

...
editable:
            {
                mode: "popup",
                template: kendo.template($("#stateProvinceEditTemplate").html())
            },

...

<script type="text/x-kendo-template" id="stateProvinceEditTemplate">
</script>

but when it pops up, it has some garbled javascript on it just like in the post above. See below and screenshot attached:

function anonymous(data) { var o,e=kendo.htmlEncode;with(data){o=' ';}return o; } 



Daniel
Top achievements
Rank 1
commented on 22 Jul 2012, 04:59 PM

This post should *not* be marked as answered.  This is definitely a bug.

<div class="k-edit-form-container">function anonymous(data) {
var o,e=kendo.htmlEncode;with(data){o='
            <div class="k-edit-label">
                <label for="IndexName">Variable Name</label>
            </div>
            <input type="text" class="k-input k-textbox" name="IndexName" data-bind="value:IndexName">
            <div class="k-edit-label">
                <label for="Description">Description</label>
            </div>
            <input type="text" class="k-input k-textbox" name="Description" data-bind="value:Description">
            <div class="k-edit-label">
                <label for="Units">Units</label>
            </div>
            <input type="text" class="k-input k-textbox" name="Units" data-bind="value:Units">
            <div class="k-edit-label">
                <label for="CompressionType">Compression</label>
            </div>
            <!-- drop down list editor for field: "CompressionType" -->
            <span tabindex="0" style="" unselectable="on" class="k-widget k-dropdown k-header"><span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input">Last Value</span><span class="k-select"><span class="k-icon k-i-arrow-s">select</span></span></span><input name="CompressionType" data-bind="value:CompressionType" data-value-field="value" data-text-field="description" data-source="compressionTypeDataSource" data-role="dropdownlist" style="display: none; "></span>
            <div class="k-edit-label">
                <label for="PointType">Point Type</label>
            </div>
            <!-- drop down list editor for field: "PointType" -->
            <span tabindex="0" style="" unselectable="on" class="k-widget k-dropdown k-header"><span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input">Calculated Variable</span><span class="k-select"><span class="k-icon k-i-arrow-s">select</span></span></span><input name="PointType" data-bind="value:PointType" data-value-field="value" data-text-field="description" data-source="pointTypeDataSource" data-role="dropdownlist" style="display: none; "></span>
             <div class="k-edit-label">
                <label for="DataType">Data Type</label>
            </div>
            <!-- drop down list editor for field: "DataType" -->
            <span tabindex="0" style="" unselectable="on" class="k-widget k-dropdown k-header"><span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input">Floating Point</span><span class="k-select"><span class="k-icon k-i-arrow-s">select</span></span></span><input name="DataType" data-bind="value:DataType" data-value-field="value" data-text-field="description" data-source="dataTypeDataSource" data-role="dropdownlist" style="display: none; "></span>
            <div class="k-edit-label">
                <label for="FieldWidth">Field Width</label>
            </div>
            <span style="" class="k-widget k-numerictextbox"><span class="k-numeric-wrap k-state-default"><input class="k-formatted-value k-input k-textbox" type="text" style="display: inline-block; " readonly="readonly"><input type="text" class="k-input k-textbox" name="FieldWidth" data-bind="value:FieldWidth" data-role="numerictextbox" style="display: none; "><span class="k-select"><span unselectable="on" class="k-link"><span unselectable="on" class="k-icon k-i-arrow-n" title="Increase value">Increase value</span></span><span unselectable="on" class="k-link"><span unselectable="on" class="k-icon k-i-arrow-s" title="Decrease value">Decrease value</span></span></span></span></span>
            <div class="k-edit-label" id="equationLabel">
                <label for="Equation" style="">Equation</label>
            </div>
            <input type="text" class="k-input k-textbox" id="equationTextBox" name="Equation" data-bind="value:Equation" style="">
            <p></p>
        ';}return o;
}<a class="k-button k-button-icontext k-grid-update" href="#"><span class="k-icon k-update"></span>Update</a><a class="k-button k-button-icontext k-grid-cancel" href="#"><span class="k-icon k-cancel"></span>Cancel</a></div>
Mo
Top achievements
Rank 1
commented on 22 Jul 2012, 05:48 PM

I found a workaround- not sure if it is just the way the new version works (documentation bug) or a true bug. instead of

kendo.template($("#editTemplate").html())

just use

$("#editTemplate").html()
Mo
Top achievements
Rank 1
commented on 22 Jul 2012, 06:24 PM

Ah... silly me... this is definitely a bug. Using just  $("#editTemplate").html() will not run any javascript in the template.
Ednei
Top achievements
Rank 1
commented on 07 Aug 2012, 11:55 AM

This is really a bug?

I get the same error on my popup edit with template.

Bug #2:
The fields that are "hidden" on my grid column definitions, are displayed in popup (without template) when I try to edit.
Daniel
Top achievements
Rank 1
commented on 07 Aug 2012, 01:27 PM

Could someone from Telerik address this by either letting the community know about a fix or workaround?

Dan
Adrian
Top achievements
Rank 1
commented on 14 Aug 2012, 10:51 PM

I just came across this issue as well. I would love an explanation, workaround, or patch. I sure hope I don't need to execute any JavaScript or conditional statements within the editor form, otherwise I'll be stuck with some raw code displaying in my custom popup editor.
Adrian
Top achievements
Rank 1
commented on 16 Aug 2012, 04:43 PM

So it turns out I do need to execute some JavaScript within the editor popup template. As a result, I require the kendo.template not break when generating the popup editor.

Here's the raw template before I put in the JavaScript code I need:

<script id="teamEditorTemplate" type="text/x-kendo-template">
    <table id="teamEditor">
        <colgroup>
            <col width="160" />
            <col width="100" />
            <col />
        </colgroup>
        <tr>
            <td rowspan="12"><img class="teamImage" width="128" height="128" data-src="/Content/images/anonymousUser.jpg" src="# if(empUserName === "null") { #/Content/images/anonymousUser.jpg# } else { #@System.Configuration.ConfigurationManager.AppSettings["EmployeePhoto"]#= empUserName #.jpg# } #" /></td>
            <td><div class="k-edit-label">
                <label for="teamId">Employee ID:</label>
            </div></td>
            <td>#= empId #</td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamFirstName">First Name:</label>
            </div></td>
            <!--<td>#= empFirstName #</td>-->
            <td><input type="text" id="teamFirstName" class="k-input k-textbox" data-bind="value:empFirstName" /></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamLastName">Last Name:</label>
            </div></td>
            <!--<td>#= empLastName #</td>-->
            <td><input type="text" id="teamLastName" class="k-input k-textbox" data-bind="value:empLastName" /></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamRole">Role:</label>
            </div></td>
            <td><input type="text" id="teamRole" class="k-input k-textbox"
                data-bind="value:empRole"
                data-value-field="empRole"
                data-text-field="empRole"
                data-source="empRoleDropDownDataSource"
                data-role="dropdownlist" /></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamCore">Core Member:</label>
            </div></td>
            <td><input type="checkbox" id="teamCore" class="k-input k-checkbox" data-bind="value:isCore" /></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamActive">Active Employee:</label>
            </div></td>
            <td><input id="teamActive" disabled="disabled" # if(empStatus !== "T") { #checked="checked"# } # type="checkbox"  class="k-input k-checkbox" /></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamHours">Hours:</label>
            </div></td>
            <td>#= hours #</td>
        </tr>
    </table>
</script>

When I tell the Kendo Grid to use that as its editor template with:

editable: {
            mode: "popup",
            template: kendo.template($("#teamEditorTemplate").html()),
            update: true,
            destroy: true,
            confirmation: "Are you sure you want to remove this team member?"
        },

I get the following output in the DOM:

<div data-role="draggable" style="padding-top: 46.2334px; display: block; top: 962.617px; left: 305.5px; z-index: 10007; opacity: 1; transform: scale(1);" class="k-widget k-window"><div style="margin-top: -46.2334px;" class="k-window-titlebar k-header"> <span class="k-window-title">Edit</span><div class="k-window-actions k-header"><a href="#" class="k-window-action k-link"><span class="k-icon k-i-close">Close</span></a></div></div><div style="min-width: 90px; min-height: 50px; overflow: auto;" class="k-window-content k-content" data-role="window" data-uid="18d8287b-f8a9-4dc8-abf4-f0dc7400fcae"><div class="k-edit-form-container">function anonymous(data) {
var o,e=kendo.htmlEncode;with(data){o='
    <table id="teamEditor">
        <colgroup>
            <col width="160">
            <col width="100">
            <col>
        </colgroup>
        <tbody><tr>
            <td rowspan="12"><img class="teamImage" data-src="/Content/images/anonymousUser.jpg" src="'; if(empUserName === " null")="" {="" ;o+="/Content/images/anonymousUser.jpg" ;="" }="" else="" +(="" empusername="" )+'.jpg';="" empid="" )+'<="" td="" height="128" width="128">
        </td></tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamFirstName">First Name:</label>
            </div></td>
            <!--<td>'+( empFirstName )+'</td>-->
            <td><input id="teamFirstName" class="k-input k-textbox" data-bind="value:empFirstName" type="text"></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamLastName">Last Name:</label>
            </div></td>
            <!--<td>'+( empLastName )+'</td>-->
            <td><input id="teamLastName" class="k-input k-textbox" data-bind="value:empLastName" type="text"></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamRole">Role:</label>
            </div></td>
            <td><span class="k-widget k-dropdown k-header k-input k-textbox" unselectable="on" style="" tabindex="0"><input style="display: none;" id="teamRole" class="k-input k-textbox k-state-default" data-bind="value:empRole" data-value-field="empRole" data-text-field="empRole" data-source="empRoleDropDownDataSource" data-role="dropdownlist" type="text"></span></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamCore">Core Member:</label>
            </div></td>
            <td><input value="false" id="teamCore" class="k-input k-checkbox" data-bind="value:isCore" type="checkbox"></td>
        </tr>
        <tr>
            <td><div class="k-edit-label">
                <label for="teamActive">Active Employee:</label>
            </div></td>
            <td><input id="teamActive" disabled="" ';="" if(empstatus="" !="=" "t")="" {="" ;o+="checked="checked"" ;="" }="" +(="" hours="" )+'<="" td="">
        </td></tr>
    </tbody></table>
     
                 
     
';}return o;
}<a class="k-button k-button-icontext k-grid-update" href="#"><span class="k-icon k-update"></span>Update</a><a class="k-button k-button-icontext k-grid-cancel" href="#"><span class="k-icon k-cancel"></span>Cancel</a></div></div></div>

When I deobfuscate the kendo.all.min.js file and poke around looking for a solution, I find this little bit of code within the "var C = B.extend" code block:

k = {
        paramName: "data",
        useWithBlock: !0,
        render: function (a, b) {
            var c, d, e = "";
            for (c = 0, d = b.length; c < d; c++) e += a(b[c]);
            return e
        },
        compile: function (b, e) {
            var f = d({}, this, e),
                g = f.paramName,
                h = g.match(E)[0],
                j = f.useWithBlock,
                k = "var o,e=kendo.htmlEncode;",
                l, m;
            if (i(b)) {
                if (b.length === 2) return function (c) {
                    return b(a, {
                        data: c
                    }).join("")
                };
                return b
            }
            k += j ? "with(" + g + "){" : "", k += "o=", l = b.replace(G, "__CURLY__").replace(F, "#=e($1)#").replace(H, "}").replace(I, "__SHARP__").split("#");
            for (m = 0; m < l.length; m++) k += D(l[m], m % 2 === 0);
            k += j ? ";}" : ";", k += "return o;", k = k.replace(J, "#");
            try {
                return new Function(h, k)
            } catch (n) {
                throw new Error(c.format("Invalid template:'{0}' Generated code:'{1}'", b, k))
            }
        }
    }

The string "var o,e=kendo-htmlEncode;" is the only verbatim piece of code I'm seeing that lines up between the awkward output in the template and the kendo source code. The obfuscation makes it extremely difficult for me to debug it myself, so I'm just going to share all this information with you and hope you can fix it since I've pointed out a good starting point.

I must say, all the difficulty we've encountered getting these widgets to work the way we need them to, combined with the incomplete documentation, and now this unfortunate bug in the code...are not compelling reasons to buy KendoUI. If we can't find ways around this, then I'm going to have to recommend the idea of pursuing an alternative to KendoUI when my boss asks me what I think of it.
Marat
Top achievements
Rank 1
commented on 18 Aug 2012, 08:10 PM

Yep, I can confirm wrong template rendering. Kendo UI team any suggestions?
alvar
Top achievements
Rank 1
commented on 20 Aug 2012, 05:36 PM

Hi All.

Thanks to a post from Adrian, i looked into Kendo source with chrome debugger. 
Adrian, you can debug Kendo source when you download the GPL version and use source/js/kendo.web.js instead of kendo.all.min.js .
So the issue seems to be that the template for grid row editor gets compiled twice...
You can see it when you examine the template argument passed to Template.compile(template, options)
Alvar


Alexander Valchev
Telerik team
commented on 21 Aug 2012, 06:14 AM

Hello guys,

This is a known issue which is already fixed in the internal builds. If you are a commercial licence owner I would recommend downloading and using the latest Kendo version.

To avoid the behaviour without upgrading, you should use the following syntax:
editable: {
    mode: "popup",
    //template: kendo.template($("#popup_editor").html())
    template: $("#popup_editor").html()
},

Here is a link to the updated jsFiddle:

Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Adrian
Top achievements
Rank 1
commented on 21 Aug 2012, 04:14 PM

Thanks Alvar. I'll take a look through the GPL version of the code and see if I might be able to wedge in a temporary patch to hold my stuff together. If not, no big deal, as I created an external function that handles the JavaScript I wanted to place within my popup editor template using a click event handler placed on the toolbar buttons.

If my team decides to purchase a KendoUI license, then I suppose we'll be granted access to this recent patch and dealing with the problem will no longer be a worry or a drain on our development time.

Best Regards,

Adrian
Marcela
Top achievements
Rank 1
commented on 03 Sep 2012, 07:46 AM

Hi.

I wondering if Can I initialize some fields when I create a new item?
Let me explain better, I've already initialize my kendogrid with my fields. Now, I want to add a new row. The new row has 3 fields, name, lastname and date, and I would like to initialize the date with a particular date. I don't want the date for today.
How can I do it?

I've been trying with databound and edit event with model property but the field that I want to initialize doesn't work. So, I need help.

Thaks in advance,
Praseeda
Top achievements
Rank 1
commented on 04 Oct 2012, 09:29 AM

I have a view.cshtml file as custom PopUp editor and Viewmodel.cs as the view model. What ever default value I set in the viewmodel  is not appearing in the Pop up editor. What could be wrong?

inside ViewModel.cs
 [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]       
        private string email = "test@sitecheck.com";
        public string Email
        {
            get { return email; }
            set { email = value; }
        }

view.cshtml

<tr>
<td>@Html.LabelFor(m => m.Email)  </td>
<td>
@Html.Kendo().AutoCompleteFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
</td>
</tr>

 

 

 

Yogoo
Top achievements
Rank 1
commented on 09 Apr 2013, 08:09 AM

THANKS FOR YOUR DEMO SO MACH.
good job guy!
0
Alexander Valchev
Telerik team
answered on 12 Jun 2012, 11:29 AM
Hello Safak,

When you use a pop up template it is recommended to set up the editor the widgets via html data attributes. Please check the following example:
<input name="FirstName"                               //name of the input
    data-bind="value:FirstName"        //model value (field from grid's dataSource
    data-value-field="firstName"      //value field from autoComplete's dataSource
    data-text-field="firstName"        //text field from autoComplete's dataSource     
    data-source="autoCompleteDS "   //dataSource for autoComplete      
    data-role="autocomplete" />                    

In case you need any further assistance, I would like to recommend to open a support ticket with your questions. Thus way you can be sure that your issue will reach the corresponding staff member in time and will be reviewed and answered faster.
Thank you in advance for your understanding.

All the best,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Safak
Top achievements
Rank 1
commented on 14 Jun 2012, 08:25 AM

Hi Alexander,

Thanks for the reply. Unfortunately below code is not working. It is not binding the data.
<input name="FirstName"                               //name of the input
    data-bind="value:FirstName"        //model value (field from grid's dataSource
    data-value-field="firstName"      //value field from autoComplete's dataSource
    data-text-field="firstName"        //text field from autoComplete's dataSource   
    data-source="autoCompleteDS "   //dataSource for autoComplete    
    data-role="autocomplete" />

Regards
Safak
Alexander Valchev
Telerik team
commented on 15 Jun 2012, 07:14 AM

Hi Safak,

I tested the suggested solution and got it working as expected on my side. Could you please check the result and let me know what I am missing?



Greetings,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Felipe Casanova
Top achievements
Rank 1
commented on 16 Jun 2012, 08:46 AM

Alexander,

To take this a bit further, if I have a dropdownlist in the popup template such as a list of addresses and I hook up a change event so that when I select an address I populate some fields in the popup, how can you update the currently edited item in that change event? I've tried by getting the currently selected item on the grid and then modifying the item in javascript but the popup doesn't update with those changes. My thinking was that this was the object bound to the popup template but it can't be. 

var model = $("#contacts").data("kendoGrid").dataItem($("#contacts").data("kendoGrid").select());
model.Forename = "foo"; // this does nothing to the popup

I've had to use jquery to update the fields on the popup directly but that seems a shame when we are using MVVM. Is there a better way to update the model via javascript? 

Thanks
Matt
Safak
Top achievements
Rank 1
commented on 17 Jun 2012, 11:36 PM

Hi Alexander,

Thank you very much for your reply again. I worked it out with your last sample codes.

Cheers!
Safak
Alexander Valchev
Telerik team
commented on 19 Jun 2012, 09:02 AM

Hello,

@Safak
I am to hear that the issue is resolved.

@Matt
To change manually the currently edited item it is recommended to work with the set method of the observable object. Thus way you can be sure that all components will be notified about the change and it will be taken into account immediately.
In order to retrieve the model at the change event of the dropDownList I suggest to use the getByUid method (the editor window contains data-uid information). For example:
.data("kendoDropDownList")
    .bind("change", function(e) {
        //get the uid from editor window
        var uid = this.element.closest("[data-role=window]").data("uid");
        //get the model from the dataSource
        var model = $("#grid").data("kendoGrid").dataSource.getByUid(uid);
        //set new values
        model.set("Age", 99);
    });

I hope this helps.

Greetings,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
Cyndie
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
Share this question
or