How to use Kendo UI Template to replace jQuery's AppendTo? - templates

Now I am using jQuery's AppendTo method to add a string element to a div for the input:
var fixedpricePanelDiv =
'<label class="control-label">Fixed price: </label>'
+'<input id="cakpriceNum" name="cakcommitprice[cakprice]" type="number"/>'
+'<input id="cakpriceunitidDdl" name="cakcommitprice[cakpriceunitid]" />';
$(fixedpricePanelDiv).appendTo($("#panel"));
<div id="panel"></div>
If I now change to KendoUI Template, how to do this?

Do the flowing
<div id="example"></div>
<script>
var template = kendo.template('<label class="control-label">Fixed price: </label>'+'<input id="cakpriceNum" name="#= cakprice#" type="number"/>'+'<input id="cakpriceunitidDdl" name="#= cakpriceunitid#" />');
var data = { cakpriceunitid: "some val",cakprice:"some val" }; //A value in JavaScript/JSON
var result = template(data); /Pass the data to the compiled template
$("#example").html(result); //display the result
</script>
More info Check the Doc http://docs.telerik.com/kendo-ui/getting-started/framework/templates/overview

Since the research from Kendo Document, I think kendo.view is used for this purpose

Related

Inline Template Editor for jsRender or other template engine

I need a component that would;
Work within a web page to allow a nontechnical user to create and edit templates for customized reports.
Allow the user to easily place a set of pre-defined template data tokens in the report that conforms to the templating engine syntax without the user needing to know how to write the syntax themselves.
Support the ability to change and update data items that can be used in the report without extensive rewriting of the code or creating a new plugin.
The goal is for end users to create their own personalized templates for a specific set of JSON data. The ability to create templates would be available on a web page and the templates would be stored for later use. Storing and using the templates is not a problem, but an easy to use editor for the templates is.
I have been using jsRender for a templating engine and like it but I am open to other engines if what I need is easier to support.
My goal is to have an online editor, similar to MCE or CKEditor, that would have the ability to place a preset list of data tokens into a custom template the user creates. These templates would be used for auto-generated content based on the data supplied to the template engine.
The solution needs to be fairly simple on the user side. The user skills could range from "Not Ignorant" up to "Almost Programmer". I would like to avoid anything that involves the user actually having to learn to hand write HTML, understand jsRender or other template library syntax. A drop down list of insertable data would be ideal.
I don't see much need for any complex logic syntax. My need is basic data token replacement, not any complex logic.
You can use jsviews + inner jsrender.
Create custom tag:
$.views.tags({
render : {
isUpdate : false,
init : function (tagCtx, linkCtx) {
var tag = this;
tag._template = tagCtx.args[0];
tag._data = tagCtx.args[1];
tag.template = "<div class='content'></div>";
},
_render : function () {
var tag = this;
var template = $.templates(tag._template.text);
tag.linkedElem.html(template.render(tag._data));
},
onUpdateTemplate : function () {
this._render();
},
onUpdateData : function () {
this._render();
},
onAfterLink : function (tagCtx, linkCtx) {
var tag = this;
tag._template = tagCtx.args[0];
tag._data = tagCtx.args[1];
if (tag._.unlinked) {
if (!tag.linkedElem) {
tag.linkedElem = tag._.inline ? tag.contents("*").first() : $(linkCtx.elem);
}
$.observable(tag._template).observeAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).observeAll($.proxy(tag.onUpdateData, tag));
} else {
$.observable(tag._template).unobserveAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).unobserveAll($.proxy(tag.onUpdateData, tag));
$.observable(tag._template).observeAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).observeAll($.proxy(tag.onUpdateData, tag));
}
tag._render();
},
onDispose : function () {
debugger;
var tag = this;
$.observable(tag._template).unobserveAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).unobserveAll($.proxy(tag.onUpdateData, tag));
},
onUpdate : function () {
return false;
},
dataBoundOnly : true
}
});
Create html:
<div id="page"></div>
<script id="templateEditor" type="text/x-jsrender">
<select data-link="selectedTemplate">
<option value="-">Please select</option>
{^{for templates}}
<option data-link="value{:#index} {:name} selected{:#index == ~root.selectedTemplate}"></option>
{{/for}}
</select>
<button data-link="{on addNew}">Add</button>
<br/>
<br/>
{^{if selectedTemplate!=="-"}}
template Name:<input data-link="templates[selectedTemplate].name" />
<br/>
<br/>
<textarea name="template" cols="40" rows="5" data-link="templates[selectedTemplate].text trigger=true"></textarea>
{{/if}}
<br/>
<br/>
{^{if selectedTemplate!=="-"}}
{^{render templates[selectedTemplate] data/}}
{{/if}}
</script>
And add app code:
var app = {
data : {
value : "test"
},
templates : [{
name : "Main",
text : "<span>{{:value}}</span>"
}
],
selectedTemplate : 0,
addNew : function () {
$.observable(this.templates).insert({
name : "new",
text : ""
});
}
};
$([app.templates]).on("arrayChange", function (o, e) {
if (e.change === "insert") {
$.observable(app).setProperty("selectedTemplate", e.index);
}
});
var templateEditor = $.templates("#templateEditor");
templateEditor.link("#page", app);
see live example on jsfiddle
Update 1:
I don't see much need for any complex logic syntax. My need is basic data token replacement, not any complex logic.
If you do not want to use jsRender use this code:
function template(str, data) {
return str.replace(/%(\w*)%/g, function (m, key) {
return data.hasOwnProperty(key) ? data[key] : "";
});
}
example on jsfiddle

dictionary requires a model item of type 'Projectname.Sp name'

i am doing a sample where i require stored procedure result have to be displayed in view(created strongly typed view by choosing details in dropdown).from service i am getting result in this format
[{"studentID":1,"studentName":"Suja","StudentDepaertment":"Economics"}]
but i get error
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[StudentForm.sp_join_details_Result]', but this dictionary requires a model item of type 'StudentForm.sp_join_details_Result'.
Homecontroller.cs
public ActionResult Details(string name)
{
studentEntities data = new studentEntities();
List<sp_join_details_Result> model = null;
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:99991/");
var response = client.GetAsync(string.Format("api/Details?name={0}", name)).Result;
var responseBody = response.Content.ReadAsStringAsync();
responseBody.Wait();
var productString = Newtonsoft.Json.JsonConvert.DeserializeObject<List<sp_join_details_Result>>(responseBody.Result);
return View(productString);
}
Details.cshtml
#model EmployAppraisalForm.sp_join_details_Result
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>sp_join_details_Result</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.studentID)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.studentID)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.studentName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.studentName)
</div>
</fieldset>
I know i have to covert the response of service to result that could be displayed in view,to which i should convert ?Please help me in this.....
Your Details() method is returning List<sp_join_details_Result> to a view which expects a single sp_join_details_Result object.
If you want to display a single object, then change the return statement to
return View(productString.FirstOrDefault());
Alternatively, if your wanting to display a collection of objects, change the view to
#model List<sp_join_details_Result>
#foreach(var item in Model)
{
....

angularjs not responding the GET method

i am relatively new in django and angualarJs.The problem is that angularJs is not responding the get method properly.I have a webpage developed by django where i have a search field.For the execution of search i use a angularJs functionality that is ng-submit and write angularJs code to return value using get method.May be i made a mistake here.you can see my code... here is my template which containing the angularJs also...
<div class="navbar navbar-default " ng-controller="NavCtrl">
<form action="" class="navbar-form navbar-right" ng-submit="search()">
<input class="form-control col-lg-8" type="text" placeholder="Search" ng-model="term"></input>
</form>
</div>
<script>
app.controller("NavCtrl", ['$scope', '$http', '$location', '$q', '$timeout',
function NavCtrl($scope, $http, $location, $q, $timeout) {
$scope.results = ["Test"];
$scope.term = "";
$scope.reqs = "5";
$scope.pics = "45";
$scope.ddata = "asdasd";
$scope.ddata = $http.post("{% url 'get-nav-info' %}").success(
function (result) {
//$scope.reqs = result.data.data.num_request;
//$scope.pics = result.data.data.num_photo;
return result.data;
}
);
//$scope.reqs = $scope.ddata.num_request;
//$scope.pics = $scope.ddata.num_photo;
$scope.search = function () {
//alert("test");
//$location.absUrl("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
//$location.path("{% url 'search-term-show' %}").search({'term':$scope.term}).apply();
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
return result.data;
});
//$scope.$apply();
}
}
]);
</script>
now the problem is that while i press enter ,there is no result,but if i manually write this URL which is http://www.kothay.com/searchphoto/?term=a in the address bar then the result is showing .In mention,this url is the that url which should be appear in the address bar when i press the enter to search my photos.But with the enter press its not appearing in the address bar and that's why the results are not showing.I hope you can understand what i am trying to say.May be there is a mistake in my code.Please help me to fix this problem.
You are doing thing wrong.
1st, the success is a defer of get, so return result.data and returns it to the get deferred and there it goes to the heaven. So if you would like to keep the current architecture it should look more like this
$scope.search = [];
getsearch = function () {
$http.get("{% url 'search-term-show' %}?term=" + $scope.term).success(function (result) {
$scope.search = result.data;
});
};
getsearch();
2nd that can still not update your UI cuz if the ctrl function is over and the digest is over before your response it wont update your UI cuz its in another scope (not $scope, but the programmatically term scope). The solution to this is to put your data in a service and in your ctr just do.
function ctrl($scope, myservice){
$scope.data = myservice;
}
ng-repeat="x in data.results"
Here is a full tutorial http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial.html
And last thing its just a good practice to always have .error(...)

Applying a Handlebars template in JavaScript code

I'm trying to use Ember's Handlebars engine for a not UI related purpose. I have a series of text templates (basically placeholders + static text), like
Order number {{number}} / {{year}}
I'm using the following code in a controller function (simplified here for the sake of the example):
formattedTitle: function(order) {
var orderTitle = "Order number {{number}} / {{year}}";
var template = Handlebars.compile(orderTitle);
return template(order);
}
offer is a Ember.data record, containing both fields.
When I run the function the resulting string only contains the static text:
Order number /
It only works with the {{id}} property, probably because you can do order.id on the Ember.data record, but not order.number (you have to use get - order.get("number"))
Any idea how to solve this?
You could use the Ember's Object.getProperties() to pull multiple properties into a simple javascript object and pass that in as the Handlebars context. Not sure that this is the best way to do this, though...
formattedTitle: function() {
var order = Ember.Object.create({number: 1, year: 2013});
// retrieve the properties ahead of time using Ember getter
var orderContext = order.getProperties(['number', 'year']);
var orderTitle = "Order number {{number}} / {{year}}";
var template = Handlebars.compile(orderTitle);
var output = template(order);
return output;
}
JSBin example
Try something like this:
function formattedTitle(order) {
var number = order.get('number');
var year = order.get('year');
var orderContext = { number: number, year: year };
var orderTitle = "Order number {{number}} / {{year}}";
var template = Handlebars.compile(orderTitle);
var output = template(orderContext);
return output;
}

CheckBoxList multiple selections: how to model bind back and get all selections?

This code:
Html.CheckBoxList(ViewData.TemplateInfo.HtmlFieldPrefix, myList)
Produces this mark-up:
<ul><li><input name="Header.h_dist_cd" type="checkbox" value="BD" />
<span>BD - Dist BD Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="SS" />
<span>SS - Dist SS Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="DS" />
<span>DS - Dist DS Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="SW" />
<span>SW - Dist SW Name </span></li>
</ul>
You can check multiple selections. The return string parameter Header.h_dist_cd only contains the first value selected. What do I need to do to get the other checked values?
The post method parameter looks like this:
public ActionResult Edit(Header header)
I'm assuming that Html.CheckBoxList is your extension and that's markup that you generated.
Based on what you're showing, two things to check:
The model binder is going to look for an object named Header with string property h_dist_cd to bind to. Your action method looks like Header is the root view model and not a child object of your model.
I don't know how you are handling the case where the checkboxes are cleared. The normal trick is to render a hidden field with the same name.
Also a nit, but you want to use 'label for="..."' so they can click the text to check/uncheck and for accessibility.
I've found that using extensions for this problem is error prone. You might want to consider a child view model instead. It fits in better with the EditorFor template system of MVC2.
Here's an example from our system...
In the view model, embed a reusable child model...
[AtLeastOneRequired(ErrorMessage = "(required)")]
public MultiSelectModel Cofamilies { get; set; }
You can initialize it with a standard list of SelectListItem...
MyViewModel(...)
{
List<SelectListItem> initialSelections = ...from controller or domain layer...;
Cofamilies = new MultiSelectModel(initialSelections);
...
The MultiSelectModel child model. Note the setter override on Value...
public class MultiSelectModel : ICountable
{
public MultiSelectModel(IEnumerable<SelectListItem> items)
{
Items = new List<SelectListItem>(items);
_value = new List<string>(Items.Count);
}
public int Count { get { return Items.Count(x => x.Selected); } }
public List<SelectListItem> Items { get; private set; }
private void _Select()
{
for (int i = 0; i < Items.Count; i++)
Items[i].Selected = Value[i] != "false";
}
public List<SelectListItem> SelectedItems
{
get { return Items.Where(x => x.Selected).ToList(); }
}
private void _SetSelectedValues(IEnumerable<string> values)
{
foreach (var item in Items)
{
var tmp = item;
item.Selected = values.Any(x => x == tmp.Value);
}
}
public List<string> SelectedValues
{
get { return SelectedItems.Select(x => x.Value).ToList(); }
set { _SetSelectedValues(value); }
}
public List<string> Value
{
get { return _value; }
set { _value = value; _Select(); }
}
private List<string> _value;
}
Now you can place your editor template in Views/Shared/MultiSelectModel.ascx...
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WebUI.Cofamilies.Models.Shared.MultiSelectModel>" %>
<div class="set">
<%=Html.LabelFor(model => model)%>
<ul>
<% for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
string name = ViewData.ModelMetadata.PropertyName + ".Value[" + i + "]";
string id = ViewData.ModelMetadata.PropertyName + "_Value[" + i + "]";
string selected = item.Selected ? "checked=\"checked\"" : "";
%>
<li>
<input type="checkbox" name="<%= name %>" id="<%= id %>" <%= selected %> value="true" />
<label for="<%= id %>"><%= item.Text %></label>
<input type="hidden" name="<%= name %>" value="false" />
</li>
<% } %>
</ul>
<%= Html.ValidationMessageFor(model => model) %>
Two advantages to this approach:
You don't have to treat the list of items separate from the selection value. You can put attributes on the single property (e.g., AtLeastOneRequired is a custom attribute in our system)
you separate model and view (editor template). We have a horizontal and a vertical layout of checkboxes for example. You could also render "multiple selection" as two listboxes with back and forth buttons, multi-select list box, etc.
I think what you need is how gather selected values from CheckBoxList that user selected and here is my solution for that:
1- Download Jquery.json.js and add it to your view as reference:
2- I've added a ".cssMyClass" to all checkboxlist items so I grab the values by their css class:
<script type="text/javascript" >
$(document).ready(function () {
$("#btnSubmit").click(sendValues);
});
function populateValues()
{
var data = new Array();
$('.myCssClas').each(function () {
if ($(this).attr('checked')) {
var x = $(this).attr("value");
data.push(x);
}
});
return data;
}
function sendValues() {
var data = populateValues();
$.ajax({
type: 'POST',
url: '#Url.Content("~/Home/Save")',
data: $.json.encode(data),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function () { alert("1"); }
});
}
</script>
3- As you can see I've added all selected values to an Array and I've passed it to "Save" action of "Home" controller by ajax 4- in Controller you can receive the values by adding an array as argument:
[HttpPost]
public ActionResult Save(int[] val)
{
I've searched too much but apparently this is the only solution. Please let me know if you find a better solution for it.
when you have multiple items with the same name you will get their values separated with coma