How to get kendo grid dropdownchange event for MVC - kendo-grid

I have used MVC kendo grid and I have bind the dropdown to grid. Now I have to get the dropdownchange event to populate other grid items by using dropdown selection.
columns.ForeignKey(c => c.CountryID, (SelectList)ViewBag.Countries).Title("Select Country");

$("#ddlTables").change(function () {
//You will get change event here
//Add debugger here and see
//Do your code here
});
columns.ForeignKey(c => c.CountryID, (SelectList)ViewBag.Countries,new {#id = "ddlCountry"}).Title("Select Country");
Here is the code replace this with your code and try to do your stuff and if still facing issue let me know

You can do it using an editor template as follows.
change the column as follows
columns.Bound(c => c.CountryID).Title("Country").EditorTemplateName("Countries").Width(300);
after that create a partial view inside views/shared/EditorTemplates with name Countries as follows
#using System.Collections
#(Html.Kendo().DropDownList()
.DataValueField("COUNTRYNAME")
.DataTextField("COUNTRYNAME")
.Name("CountryID")
.BindTo((IEnumerable)ViewBag.Countries)
.OptionLabel("Select Country")
.Filter(FilterType.Contains)
.Events(e =>
{
e.Change("CountryChange");
})
)
After this you can write jquery as follows
<script>
function CountryChange()
{
//You will get change event here
}

Related

How can we add a custom dropdown in tiny mce using yii2

I want to add a custom drop down in tiny mce editor, I am using yii framework and using a yii plugin to integrate the editor
You haven't added any details in your question but since you are a new
bee here and SO Code of Conduct
has been revised to be more nice and humble towards newcomers, so I am
adding the answer for you, do go through the How to Ask a
Question? before posting a
question next time.
You can add the dropdown in the TinyMCE using setup option which takes a callback function with a parameter editor which holds the editor instance, and then you need to call the editor.addButton(label, options) with the options to create the custom dropdown button.
As you have not added any details in the question like what are the options that you are going to display in the dropdown so, I will assume here as usernames from the database in the variable $users.
Steps to Implement
First, we will convert $users array to js array by using yii\helpers\Json::encode().
Iterate that array to create the drop-down options with onclick event to insert the content to the editor.
Use editor.addButton('users',options) to create a button of type dropdown with label users to be later used when initializing the editor toolbar buttons.
Add the following code on top of the view
$usersList = \yii\helpers\Json::encode($users);
$tinyMCECallback = <<< JS
function (editor) {
let usersList = $usersList;
let options = [];
//iterate the user array and create the options with text and
//onclick event to insert the content on click to the editor
$.each(usersList, function(label, mapping) {
options.push({
text: label,
onclick: function() { tinymce.activeEditor.insertContent(label); }
});
});
//add the dropdown button to the editor
editor.addButton('users', {
type: 'menubutton',
text: 'Users',
icon: false,
menu: options
});
}
JS;
Now all you need to do is to pass the $tinyMCECallback to the setup option of the tinyMCE widget, if you are using the active form you code should be like below.
Note: Don't forget to add the users label of the button to the toolbar options, or if you change it in the javascript code change it accordingly in the editor toolbar options otherwise it won't show up
<?php
echo $form->field(
$model, 'body'
)->widget(
TinyMce::class, [
'options' => ['rows' => 10],
'language' => 'en',
'clientOptions' => [
'menubar' => false,
'statusbar' => false,
'toolbar' => "undo redo | users",
'setup' => new \yii\web\JsExpression($tinyMCECallback),
],
]
);
?>

Button in Kendo Grid, on click update field

In my Kendo Grid I have a column that I'd like to contain a button.
On clicking this button, I'd like to populate one of fields in the grid (called TradesmanId) with an ID that is available to a javacript function (it is the ID of a logged in user).
This ID should sit in the field until the save changes event on the grid is called.
I had thought about defining the column like this, but I wonder if a command column would work better?
.Columns(trdcol =>
{
trdcol.Bound(f => f.TradeHrs).Title("Man Hours").Width(45);
trdcol.Bound(f => f.TradeDate).Title("Time Date").Width(77).ClientTemplate("#= kendo.toString(TradeDate, 'hh:mm dd/MM/yyyy') #");
trdcol.Bound(p => p.TradesmanId).ClientTemplate("<button id='button' class='k-button'><span class='k-icon k-i-check-outline'></span> #= TradesmanId#</button>").Title("Signature").Width(85);
})
What you did is fine. You can just add a class to your button and then add a click handler that'll do the following:
$(document).on("click", "buttton.my-class", function(e) {
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataSource.getByUid($(this).closest("tr").data("uid"));
dataItem.TradesmanId = getLoggedInUserId(); //your javascript function returning the user id
grid.refresh();
})

Handling events from a Kendo MVC Grid's PopUp editor window

I have a Kendo MVC grid that I am creating with the Html.Kendo().Grid helper. When the PopUp editor window opens, I want to catch the event and run a bit of javascript. When I configure a normal kendo window with .Events, the events fire properly and my function runs. However, when I code the .Events property on the .Editable.Window of the grid, the events do not fire.
#(Html.Kendo().Grid<FooRecord>()
.Name("cFooGrid")
.Columns(c =>
{
c.Bound(f => f.Foo);
c.Bound(f => f.Bar);
c.Bound(f => f.Bas);
c.Command(a => a.Edit());
})
.Editable(e => e
.Mode(GridEditMode.PopUp)
.Window(w => w.Events(v => v.Open("OnEditStart").Activate(#<text>function () {console.log("EditWindow.Activate")}</text>)))
)
.ToolBar(t =>
{
t.Create();
})
.DataSource(ds => ds
.Ajax()
.Create(r => r.Action("UpdateIndex", "Home"))
.Read(r => r.Action("IndexList", "Home"))
.Update(u => u.Action("UpdateIndex", "Home"))
.Model( m => {
m.Id(f => f.Foo);
})
)
)
When I review the generated code in Chrome's developer tools, the window is generated without the Activate or Open features:
jQuery(function(){jQuery("#cFooGrid").kendoGrid({"columns":[{"title":"Foo Key","field":"Foo","encoded":true,"editor":null},{"title":"Bar Field","field":"Bar","encoded":true,"editor":null},{"title":"Bas Value","field":"Bas","encoded":true,"editor":null},{"command":[{"name":"edit","buttonType":"ImageAndText","text":"Edit"}]}],"scrollable":false,"editable":{"confirmation":"Are you sure you want to delete this record?","confirmDelete":"Delete","cancelDelete":"Cancel","mode":"popup","template":"\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"Foo\"\u003eFoo Key\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" id=\"Foo\" name=\"Foo\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Foo\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"Bar\"\u003eBar Field\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" data-val=\"true\" data-val-maxlength=\"The field Bar Field must be a string or array type with a maximum length of \u0026\\#39;20\u0026\\#39;.\" data-val-maxlength-max=\"20\" id=\"Bar\" name=\"Bar\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Bar\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e\u003cdiv class=\"editor-label\"\u003e\u003clabel for=\"Bas\"\u003eBas Value\u003c/label\u003e\u003c/div\u003e\u003cdiv class=\"editor-field\"\u003e\u003cinput class=\"k-textbox\" data-val=\"true\" data-val-required=\"The Bas Value field is required.\" id=\"Bas\" name=\"Bas\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Bas\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e\u003c/div\u003e","window":{"title":"Edit","modal":true,"draggable":true,"resizable":false},"create":true,"update":true,"destroy":true},"toolbar":{"command":[{"name":null,"buttonType":"ImageAndText","text":"Add new record"}]},"dataSource":{"type":(function(){if(kendo.data.transports['aspnetmvc-ajax']){return 'aspnetmvc-ajax';} else{throw new Error('The kendo.aspnetmvc.min.js script is not included.');}})(),"transport":{"read":{"url":"/Home/IndexList"},"prefix":"","update":{"url":"/Home/UpdateIndex"},"create":{"url":"/Home/UpdateIndex"}},"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"filter":[],"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"id":"Foo","fields":{"Foo":{"type":"string"},"Bar":{"type":"string"},"Bas":{"type":"string"}}}}}});});
Or, more specifically:
"window":{"title":"Edit","modal":true,"draggable":true,"resizable":false}
I would expect that the window would be generated with Activate: and Open: parameters, but they don't show up. Can anyone give me a pointer as to whether this just isn't supported or I am doing something wrong?
Edit:
So in order to capture the events as above, there are two steps:
Add this to the grid definition (remove the Window .Events)
.Events(e => e.Edit("OnEditStart"))
Then add a javascript function like this to the page.
function OnEditStart(pEvent) {
var editWindow = pEvent.container.data('kendoWindow');
editWindow.bind('activate', function () {
console.log('Edit start event fired');
});
}
NOTE: There does not appear to be any way to capture the open event since this event is fired on the window before the edit event on the grid.
The "events" of the kendo grid popup are not honoured/serialized (at least not the last time I tested this back in 2014) and so you should use the grid's Edit event to control the "Pop Up" window events
So within your grid add this:
.Events(event => event.Edit("onEdit"))
.//other grid settings here.
Then add a javascript function like this:
function onEdit(e) {
//get window object
var kendoWindow = e.container.data("kendoWindow");
kendoWindow.setOptions({
title: "I have a custom Title"
//do stuff in here
});
}
Then you can apply what ever functions you want to the window via javascript.
I do something similar to this to resize the pop up editor so it takes up 80% of the screen size regardless of the display/device.
If you have something more specific you are after then I will update my answer accordingly.
edit: If you want you can refer to this post from Telerik's own forums which is what I used when I first encountered this issue back in mid 2014.
Kendo Pop Up Editor not firing off applied events

Kendo Grid Fluent API DataBound event for a Child Grid to show No Items text?

It feels like i've lost a lot of time looking for this and still haven't found anything that works (well, that works properly). I have a set of nested grids for a user requirement, each one drills down into the next one etc and all that is working fine. It's handled using client templates which do an ajax call when they get expanded, and then displays the data.
The problem I have is that if there are no results for one of the expansions, Kendo just shows the child grid header and nothing else. When I connect to the DataBound event (on the grid, .Events(e => e.DataBound("myJavaScriptFunctionName")) the this is not the Kendo Grid, and if I pass the name of the child kendo grid (which is unique by using the key in #=#) it gives me 0 items in my data source.
I'm not sure if this is because it does an ajax post back, and then OnDataBound fires before it comes back?
I just need to show a "No Items Found" message to make the user experience better when there is no data (this really only happens at the lowest level)
Enough with words, here is some example code:
<script id="SecondToLastTemplate" type="text/kendo-tmpl">
#(Html.Kendo().Grid<CustomerViewModel>()
.Name("SumGrid_#=ResultYear#_#=ResultQuarter#_#=ResultMonth#_#=ResultWeekStart#_#=ResultDate#_#=Region#")
.Columns(column =>
{
column.Bound(x => x.CustomerName).Width("23%");
column.Bound(x => x.CustomerSummaryItem1).Width("14%");
column.Bound(x => x.CustomerSummaryItem2).Width("14%");
column.Bound(x => x.CustomerSummaryItem3).Width("14%");
})
.DataSource(dataBinding => dataBinding
.Ajax()
.PageSize(500)
.Read(read => read.Action("GetCustomerSummaryItems", Constants.Controller_ReportController, new
{
ResultYear = "#=ResultYear#"
,ResultQuarter = "#=ResultQuarter#"
,ResultMonth = "#=ResultMonth#"
,ResultWeekStart = "#=ResultWeekStart#"
,ResultDate = "#=ResultDate#"
,Region = "#=Region#"
}))
)
.Scrollable(scrolling => scrolling.Enabled(false))
.Sortable()
.Filterable(filtering => filtering.Enabled(true))
.ClientDetailTemplateId("LastTemplate")
.Pageable(paging => paging.Enabled(false))
.ToClientTemplate()
)
</script>
<script id="LastTemplate" type="text/kendo-tmpl">
#(Html.Kendo().Grid<CustomerDetailsViewModel>()
.Name("SumGrid_#=ResultYear#_#=ResultQuarter#_#=ResultMonth#_#=ResultWeekStart#_#=ResultDate#_#=Region#_#=CustomerName#")
.Columns(column =>
{
column.Bound(x => x.CustomerDetails1).Width("23%");
column.Bound(x => x.CustomerDetails2).Width("20%");
column.Bound(x => x.CustomerDetails3).Width("35%");
column.Bound(x => x.CustomerDetails4).Width("14%");
})
.DataSource(dataBinding => dataBinding
.Ajax()
.PageSize(500)
.Read(read => read.Action("GetCustomerDetails", Constants.Controller_ReportController, new
{
ResultYear = "#=ResultYear#"
,ResultQuarter = "#=ResultQuarter#"
,ResultMonth = "#=ResultMonth#"
,ResultWeekStart = "#=ResultWeekStart#"
,ResultDate = "#=ResultDate#"
,Region = "#=Region#"
,CustomerName = "#=CustomerName#"
}))
)
.Events(e => e.DataBound("onDataBound"))
.Scrollable(scrolling => scrolling.Enabled(false))
.Sortable()
.Filterable(filtering => filtering.Enabled(true))
.Pageable(paging => paging.Enabled(false))
.ToClientTemplate()
)
</script>
OnDataBound i've tried a few things, including the answer from this thread (Display a message within the Kendo grid when it's empty) with no luck. That one specifically always tells me I have 0 items in my data source (originally it was undefined, then I passed the grid name and still no luck).
Does anyone have a nice way to just say "No Items to display" while using the Fluent API with nested grids? I feel like i'm missing something simple here.
Thank you!
I figured these out:
Since I was using an ajax post back, the grid items weren't always available when the DataBound event was being called for some reason (it feels like they should be, since it's DataBound, but it wasn't)
I wrapped my no-results query in a setTimeout of 500ms so as to catch it, anything less and I would go back to the original error. I also modified the .find(... call to remove k-grid-header since that class wasn't outputting on my grid, and the colgroup was directly under the k-grid on the table.
function DisplayNoResultsFound(e) {
var self = e;
setTimeout(function (item) {
var grid = self;
var dataSource = grid.data('kendoGrid').dataSource;
var colCount = grid.find('colgroup > col').length;
var noResultsMessage = '#Resources.Global.NoResultsFound';
// If there are no results place an indicator row
if (dataSource._view.length == 0) {
grid.find('tbody')
.append('<tr class="kendo-data-row"><td colspan="' + colCount + '" style="text-align:center"><b>' + noResultsMessage + '</b></td></tr>');
}
}, 500); //Need to delay for ajax postback
}
This code is called by passing the jQuery grid item from the Databound Event:
.Events(e => e.DataBound(DisplayNoResultsFound($('\\#SumGrid_#=ResultYear#_#=ResultQuarter#_#=ResultMonth#_#=ResultWeekStart#_#=ResultDate#_#=Region#_#=CustomerName#'))")
Hope this helps someone else in the future!

Kendo MVC - Persist and load grid buttons

I am trying to persist my grid data and following this example.
This works very well for me but the problem is I am having Excel Import button in my grid and after loading the persisted state of the grid, the Excel Export button is disappeared.
This is my code for the grid (data persisting code is not here, it is same as the above example).
#(Html.Kendo().Grid<DtoTaskExtended>()
.Name("AdraKendoGrid")
.TableHtmlAttributes(CodeTaskKendoGrid.GetTableHtmlAttributes())
.RowAction(CodeTaskKendoGrid.GridPerRowAction)
.CellAction(CodeTaskKendoGrid.GridCellsConfigurator)
.Columns(CodeTaskKendoGrid.ColumnsConfigurator)
.ToolBar(tools => tools.Excel())
.Pageable(pager => pager.PageSizes(new int[] { 15, 50, 100, 500 })
.Info(true)
.Messages(message => message.Display("{0} - {1} " + Strings.of + "{2} " + Strings.items))
.Messages(message => message.ItemsPerPage(Strings.itemsPerPage))
.Messages(message => message.Empty(Strings.noItemsToDisplay)))
.Sortable()
.Groupable(gr => gr.Messages(message => message.Empty(Strings.kendoGroupMsg)))
.Excel(excel => excel
.AllPages(true)
.FileName("Task Grid Export.xlsx")
.Filterable(true)
.ProxyURL(Url.Action("Excel_Export_Save", "Task")) //.ForceProxy(true)
)
.Filterable()
.Reorderable(reorder => reorder.Columns(true))
.Resizable(r => r.Columns(true))
.ColumnMenu()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Read(read => read.Action("GetTaskResult", "Task")))
.ClientDetailTemplateId("client-template")
)
Data is saved and loaded correctly, but the grid buttons (Export to Excel) button is disappeared after loading data.
How do I persist the button of the gird?
Thank you.
Hi I have a same issue like you and i solve my problem like this
function load() {
var grid = $('#gr').data("kendoGrid");
var toolBar = $("#grid .k-grid-toolbar").html();
var options = localStorage["kendo-grid-options-log"];
if (options) {
grid.setOptions(JSON.parse(options));
$("#grid .k-grid-toolbar").html(toolBar);
$("#grid .k-grid-toolbar").addClass("k-grid-top");
}
}
There is a limitation for making the toolbar persistent. A note about it from the kendo docs:
An important limitation when using the setOptions method in combination with the MVC wrappers is that any toolbar or header server templates (razor syntax #) will be lost and the layout will become incorrect once the method is invoked. Those options cannot be persisted because there is no JavaScript equivalent option for them since they contain server side logic. Consider using JavaScript initialization (instead of the MVC wrapper). An alternative is to specify the same option with the JavaScript equivalent.
Here's a possible solution:
Persist state issues
I'm not a developer, but ran across the same problem with using javascript. I had to put the entire template code in the grid options, instead of pointing to an HTML template.
I hope that points you in the right direction.
After a long research I was able to find a real and workable solution:
https://github.com/telerik/ui-for-aspnet-mvc-examples/blob/master/grid/grid-preserve-server-toolbar-template-after-set-options/GridPerserveToolbarServerTemplate/Views/Home/Index.cshtml
You need to add the following code to your View:
Razor:
#helper ToolbarTemplate() {
<a class="k-button k-button-icontext k-grid-save-changes" href="javascript:void(0)"><span class="k-icon k-update"></span>Save changes</a>
<a class="k-button k-button-icontext k-grid-cancel-changes" href="javascript:void(0)"><span class="k-icon k-cancel"></span>Cancel changes</a>
}
<script type="text/x-kendo-template" id="toolbarTemplate">
#Html.Raw(#ToolbarTemplate().ToHtmlString().Replace("#", "\\#").Replace("</scr", "<\\/scr"))
</script>
JavaScript:
<script>
//Here you define the ID of your grid
var grid = $("#grid").data("kendoGrid");
//Here you get the local settings for your case
var options = localStorage["settings"];
//To verify if there is anything stored
if (options) {
//To parse the result
var parsedOptions = JSON.parse(options);
//To display the toolbar
parsedOptions.toolbar = [
{ template: $("#toolbarTemplate").html() }
];
//To set the stored changes
grid.setOptions(parsedOptions);
}
</script>
What is the trick?
You need to get code generated the first time before saving the state (you can get it with inspect element).
And add it to the ToolbarTemplate(), after that the toolbar is going to be stored too.
Also, in the above link you can read more about headers if you want to stored them too, it will be a similar code.
The code that I showed it's fully tested and it's working 100% of cases.
If you a doubt of why this is happening, as far as I know it's related to the fact that the Toolbar is created on the server side while the states are done on the client side.