Kendo UI - Set parameter programmatically - javascript

# var myVar = false; #
<div>
#(Html.Kendo().Stepper()
.Name("stepper")
.Orientation(StepperOrientationType.Horizontal)
.Label(true)
.Indicator(true)
.Steps(s =>
{
s.Add().Label("Step_1");
s.Add().Label("Step_2").Selected(true);
s.Add().Label("Step_3");
})
.ToClientTemplate())
</div>
The above sets Step_2 to be the selected one.
How do I set it programmatically?
e.g. s.Add().Label("Step_2").Selected(myVar);

You are messing languages layers. myVar is Javascript and its inside a template, Html.Kendo()... is c#, so you CAN'T mix them. You have to change it outside the template.
What I would do is something like this:
<div id="stepper-container" data-step="#= myVar #">
Then after the template was rendered, I would use Javascript to change that:
let stepperIndex = $('#stepper-container').data('step');
$('#stepper').data('kendoStepper').select(stepperIndex);

Related

How to use injected constants in html file in AngularJS

I have a constant file which looks like this
demo.constant.js
// Add detail constans here
(function () {
angular.module('myApp').constant('TYPE', {
DYNAMIC: 'dynamic',
STATIC: 'static'
});
}());
Now I have a controller file that looks similar to this.
demo.controller.js
(function() {
var DemoController = function(DEP1,DEP2, .... , TYPE)
console.log(TYPE.DYNAMIC); // works perfectly
var self = this;
self.type = '';
...
...
angular.module('myApp.controllers').controller('DemoController', DemoController);
})();
I am trying to access these constants in the HTML file like this:-
<div ng-controller="DemoController as self">
<span ng-if="(self.type === 'dynamic')"> <!--instead of 'dynamic' I want to use TYPE.DYNAMIC-->
...
...
...
</span>
</div>
Note:- {{self.type}} works but {{TYPE.DYNAMIC}} doesn't.
Another problem is that I want to use this constant as the value of radio buttons.
somewhat like this:-
<input type="radio" name="type" ng-model="self.inputType" value="dynamic"> <!-- Here I want to use TYPE.DYNAMIC -->
<input type="radio" name="type" ng-model="self.inputType" value="static"> <!-- Same as above -->
I have searched everywhere but nothing seems to work. Please Help!!
One approach is to assign the constant to a controller property:
function DemoController(DEP1,DEP2, /*.... ,*/ TYPE) {
console.log(TYPE.DYNAMIC); // works perfectly
this.TYPE = TYPE;
}
angular.module('myApp.controllers').controller('DemoController', DemoController)
Then use it in the template:
<div ng-controller="DemoController as $ctrl">
<span ng-if="$ctrl.type === $ctrl.TYPE.DYNAMIC">
...
</span>
</div>
Note: The ng-if directive uses creates a child scope. Consider instead using the ng-show directive which uses CSS and less resources.
You can use $rootScope and initilize it in run phase:
angular.module('app')
.run(function ($rootScope, TYPE) {
$rootScope.TYPE = TYPE
});
then you can use it directly in your HTML

Different way of parsing through value part of key-value pair in AngularJS

I have a key-value pair that looks something like this ($ctrl.displayData)-
143:"/this/is/a/very/long/fil22↵/this/is/a/very/long/file/path.php↵anotherone.php↵newfilel123.php"
It saves file names and when I display it with an ng-repeat, file names are displayed in newlines (just as I want).
For display I use-
<div>
<div id="outputDiv" ng-click="$ctrl.deleteRow(displayData)" ng-repeat="displayData in $ctrl.displayData">{{displayData}}</div>
</div>
The function deleteRow() is pretty basic as of now-
ctrl.deleteRow = function(index){
console.log(index);
}
But when I loop through using ng-repeat, the entire {{displayData}} gets printed in just one iteration, so if I were to call a function like deleteRow() on click of any one file name, it just returns the entire set of file names each time (and not the particular file name that I have clicked on).
Is there a way of looping through $ctrl.displayData in such a way that on clicking any particular file name, the function is called only for that file name.
could you use javascript split?
// <body ng-app='myApp' binds to the app being created below.
var app = angular.module('myApp', []);
// Register MyController object to this app
app.controller('MyController', ['$scope', MyController]);
// We define a simple controller constructor.
function MyController($scope) {
$scope.files = "/this/is/a/very/long/fil22 \n /this/is/a/very/long/file/path.php \n anotherone.php \n newfilel123.php"
$scope.split = function(s) {
return s.split('\n');
}
$scope.doStuff = function(d) {
console.log(d);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller='MyController'>
<p ng-repeat="d in split(files)">
<span ng-click="doStuff(d)">{{d}}</span>
</p>
</div>
</div>
I handled it inside the JS controller (using split there).
ctrl.arrayList = new Array();
for(var i in ctrl.displayData) {
ctrl.arrayList = ctrl.displayData[i].split('\n');
}
return ctrl.arrayList;
After this I use an ng-repeat on the array ctrl.arrayList for display inside the HTML file.

How to render Html tags passed as string property in React.js

Is it possible to pass HTML tags as properties and then render in React.js
For example ES2015 syntax:
I add the property as a string with HTML tags:
renderItems(posts) {
var groupDate = this.props.item.date.toUpperCase();
var listCol = '<h4>' + groupDate.toString() + '</h4>';
return (<ViewList list={posts} postCol1={listCol}/>);
}
And in my ViewList component I have:
<div className="col-md-9">{this.props.postCol1}</div>
This is rendered as :
<h4>JANUARY 28TH, 2016</h4>
How do I get react to render the date excluding the HTML tags?
Different views uses this component and tags may be different explaining why I would like to include the tag.
This actually worked:
renderItems(posts) {
var groupDate = this.props.item.date.toUpperCase();
return (<ViewList list={posts} postCol1={<h4>{groupDate.toString()}</h4>}/>);
}
Take the <h4> tags out of the listCol string. Your ViewList component should render them:
<div className="col-md-9">
<h4>
{this.props.postCol1}
</h4>
</div>

Dynamically creating kendo-grid columns in angular controller

I am trying to dynamically build the structure of a kendo-angular grid. My problem is that the grid options are not known when the k-options attribute is evaluated, so the grid is binding to ALL of the columns on the datasource.
Here is the HTML:
<div kendo-grid k-options="{{gridModel.options}}"
k-data-source="gridModel.myDataSource">
</div>
And here is the javascript in the controller:
// this is called after the api call has successfully returned with data
function getSucceeded(){
...
$scope.gridModel.options = function(){
// function that properly builds options object with columns, etc.
}
// this is just shown for example... the data is properly loading
$scope.gridModel.myDataSource.data(ds.data());
}
The data is properly loading, but because gridModel.options was evaluated in the HTML prior to being set by the success method, it is essentially ignored and all of the columns from the datasource are being rendered.
This works like a champ when gridModel.options is static.
How can I defer the evaluation of k-options and/or force a reevaluation after they've been set by the controller?
I was able to figure it out. I had to do four things:
Update my version of angularjs (I was on 1.08 which does not have the ng-if directive). I updated to 1.2.0rc3.
Wrap my kendo-grid div in an ng-if div
Invoke my function! I was just setting $scope.gridModel.options to a function - I needed to actually invoke the function so I'd be setting the variable to the value returned from the function.
I had to update my angular.module declaration to include ngRoute (based on it being separated into it's own module in 1.2.x).
Here's the updated HTML:
<div data-ng-if="contentAvailable">
<div kendo-grid k-options="{{gridModel.options}}"
k-data-source="gridModel.myDataSource">
</div>
</div>
And here's the updated controller (not shown: I set $scope.contentAvailable=false; at the beginning of the controller):
// this is called after the api call has successfully returned with data
function getSucceeded(){
...
$scope.gridModel.options = function(){
// function that dynamically builds options object with columns, etc.
}(); // <----- NEED to invoke function!!
// this is just shown for example... the data is properly loading
$scope.gridModel.myDataSource.data(ds.data());
$scope.contentAvailable=true; // trigger the ng-if
}
I actually moved the function into a config file so I'm not polluting the controller with too much configuration code. Very happy to have figured this out.
Here is a sample using 'Controller As' syntax, dynamic columns and paging.
var app = angular.module("app", ["kendo.directives"]);
function MyCtrl() {
var colsList = [{
name: "col1"
}, {
name: "col2"
}, {
name: "col3"
}, {
name: "col4"
}];
var gridCols = [];
var iteration = 1;
var vm = this;
vm.gridOptions = {
columns: gridCols,
dataSource: new kendo.data.DataSource({
pageSize: 10
}),
pageable: true
};
vm.buildGrid = function() {
var data = {};
vm.gridOptions.columns = [];
for (var x = 0; x < colsList.length; x++) {
if (iteration % 2 === 0 && x === colsList.length - 1) continue;
var col = {};
col.field = colsList[x].name;
col.title = colsList[x].name;
data[col.field] = "it " + iteration + " " + (1111 * (x + 1));
vm.gridOptions.columns.push(col);
}
// add one row to the table
vm.gridOptions.dataSource.add(data);
iteration++;
};
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.default.min.css" />
<script src="http://cdn.kendostatic.com/2015.1.318/js/kendo.all.min.js"></script>
<body ng-app="app">
<div ng-controller="MyCtrl as vm">
<button ng-click="vm.buildGrid()">Build Grid</button>
<div kendo-grid="grid" k-options="vm.gridOptions" k-rebind="vm.gridOptions"></div>
</div>
</body>
We can use the k-rebind directive for this. From the docs:
Widget Update upon Option Changes
You can update a widget from controller. Use the special k-rebind attribute to create a widget which automatically updates when some scope variable changes. This option will destroy the original widget and will recreate it using the changed options.
Apart from setting the array of columns in the GridOptions as we normally do, we have to hold a reference to it:
vm.gridOptions = { ... };
vm.gridColumns = [{...}, ... ,{...}];
vm.gridOptions.columns = vm.gridColumns;
and then pass that variable to the k-rebind directive:
<div kendo-grid="vm.grid" options="vm.gridOptions" k-rebind="vm.gridColumns">
</div>
And that's it when you are binding the grid to remote data (OData in my case). Now you can add or remove elements to/from the array of columns. The grid is going to query for the data again after it is recreated.
When binding the Grid to local data (local array of objects), we have to somehow postpone the binding of the data until the widget is recreated. What worked for me (maybe there is a cleaner solution to this) is to use the $timeout service:
vm.gridColumns.push({ ... });
vm.$timeout(function () {
vm.gridOptions.dataSource.data(vm.myArrayOfObjects);
}, 0);
This has been tested using AngularJS v1.5.0 and Kendo UI v2016.1.226.

How do i get a value from Kendo UI template

I have this template:
var template = kendo.template("<div class='relatedItemRow'>"
+ "<span id='relatedItemName'>Related Item #: Number #</span>"
+ "<div class='relatedItemRowInfo'><span >#: Name #</span>"
+ "<a data-relatedItemID='#: Value #' class='removeRelatedItem'>"
+ "<img src= '#: Img #'/</a></div><br class='clear'/></div>");
var data = {
Name: "" + checkbox.getAttribute('flatName'),
Number: $('#relatedItemsList').children().length + 1,
Img: '/Content/images/x_remove.png',
Value: checkbox.value
};
var result = template(data);
$("#relatedItemsList").append(result);
I am able to access the data-relatedItemID by using:
$('#relatedItemsList').children().eq(i).children().last().attr('data-relatedItemID')
But how do I get to the Number field in data? I want to change that one dynamically.
I have tried:
$('#relatedItemsList').children().eq(i).children().attr('Number') == 5
but it does not work. Any idea how to do that?
I know that there is an answer for this question even accepted but I'd like to suggest a different approach that I think it is much simpler and more Kendo UI oriented and is using Kendo UI ObservableObject. This allows you to update an HTML that is bound to the ObservableObject without having to crawl the HTML.
This approach is as follow:
Wrap your data definition with a Kendo Observable Array initialization.
Redefine your template and start using using data-binding.
Append this new template to your HTML.
Bind data to the HTML.
Now you can get current value using data.get("Number") or set a new value using data.set("Number", 5) and the HTML get magically updated.
The code is:
Template definition
<script type="text/kendo-template" id="template">
<div class='relatedItemRow'>
<span id='relatedItemName'>Related Item <span data-bind="text : Number"></span></span>
<div class='relatedItemRowInfo'>
<span data-bind="html : Name"></span>
<a class='removeRelatedItem' data-bind="attr: { data-relatedItemID : Value }">
<img data-bind="attr : { src : Img }"/>
</a>
</div>
<br class='clear'/>
</div>
</script>
data definition as:
var data = new kendo.data.ObservableObject({
Name: "" + checkbox.getAttribute('flatName'),
Number: $('#relatedItemsList').children().length + 1,
Img: '/Content/images/x_remove.png',
Value: checkbox.value
});
and the initialization of the HTML is:
$("#relatedItemsList").append($("#template").html());
Getting current value of Number is:
var old = data.get("Number");
Setting is:
data.set("Number", 5);
Running example in JSFiddle here : http://jsfiddle.net/OnaBai/76GWW/
The variable "result" and thus the data you're trying to change aren't a Kendo templates, they're just html created by the template, and the number is just text in the html. To modify the number without rebuilding the whole string, you need to change the template so you can select the number by itself with jQuery by putting it in it's own element, and adding something to identify it.
var template = kendo.template("<div class='relatedItemRow'><span id='relatedItemName'>Related Item <span class='relatedNumberValue'>#: Number #</span></span><div class='relatedItemRowInfo'><span >#: Name #</span><a data-relatedItemID='#: Value #' class='removeRelatedItem'><img src= '#: Img #'/</a></div><br class='clear'/></div>");
//other code the same
And once you can select it, then you can change it like this.
$('#relatedItemsList').children().eq(i).find('.relatedNumberValue').text(5);
And retrieve it like this.
var foo = $('#relatedItemsList').children().eq(i).find('.relatedNumberValue').text();

Categories

Resources