Implementing textarea Drag and drop - javascript

(function() {
'use strict';
var data = JSON.stringify({
"tags": [{
"id": 1,
"name": "HELPDESKPHONE",
"value": "{{helpdeskphone}}",
"description": null
}, {
"id": 3,
"name": "HELPDESKEMAIL",
"value": "{{helpdeskemail}}",
"description": null
}, {
"id": 4,
"name": "CODE",
"value": "{{code}}",
"description": null
}, {
"id": 7,
"name": "CALLBACKURL",
"value": "{{callbackurl}}",
"description": null
}],
"templates": [{
"id": 1,
"key": "securitycode",
"description": null,
"content": "<p>Your credentials have been identified in the system and a request to authenticate your account by email has been made.</p><p>To continue the 2-Factor Authentication process, enter this single-use code on the verification page.</p>{{code}}<p>PLEASE NOTE THAT THIS CODE EXPIRES WITHIN 1 HOUR OF SENDING THIS EMAIL.</p><p>If you did not initiate this request, please contact the Helpdesk via email at {{helpdeskemail}} or by calling (toll-free) {{helpdeskphone}}</p>",
"subject": "Security Code"
}, {
"id": 3,
"key": "resetpassword",
"description": null,
"content": "<p>A request to change your password has been made. To continue the password change process, click on the link below.</p>Click here to reset your password.</p>\n<p>PLEASE NOTE THAT THIS LINK EXPIRES WITHIN 1 HOUR OF SENDING THIS EMAIL.</p><p>If you did not initiate this request, please contact the Helpdesk via email at {{helpdeskemail}}; or by calling (toll-free) {{helpdeskphone}}</p> ",
"subject": "FWIMS Password Change Request"
}]
});
var Tag = function(id, name, value, description) {
var self = this;
self.id = ko.observable(id);
self.name = ko.observable(name);
self.value = ko.observable(value);
self.description = ko.observable(description);
};
var Template = function(id, key, description, content, subject, tags) {
var self = this;
self.id = ko.observable(id);
self.key = ko.observable(key);
self.description = ko.observable(description);
self.content = ko.observable(content);
self.subject = ko.observable(subject);
};
var ViewModel = function(data) {
var self = this;
self.templates = ko.observableArray(data.templates.map(function(item) {
return new Template(
item.id,
item.key,
item.description,
item.content,
item.subject
);
}));
self.tags = ko.observableArray(data.tags.map(function(item) {
return new Tag(
item.id,
item.name,
item.value,
item.description
);
}));
self.makeDraggable = function() {
$("li").draggable({
helper: 'clone'
});
};
self.makeDroppable = function(elements) {
$(".txtDropTarget").droppable({
accept: "li",
drop: function(ev, ui) {
$(this).insertAtCaret(ui.draggable.text());
}
});
};
$.fn.insertAtCaret = function(myValue) {
return this.each(function() {
//IE support
if (document.selection) {
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
}
//MOZILLA / NETSCAPE support
else if (this.selectionStart || this.selectionStart == '0') {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var scrollTop = this.scrollTop;
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
this.focus();
this.selectionStart = startPos + myValue.length;
this.selectionEnd = startPos + myValue.length;
this.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
});
};
};
var viewModel = new ViewModel(ko.utils.parseJson(data) || []);
ko.applyBindings(viewModel);
}());
.move-pointer {
cursor: move;
}
<div data-bind="foreach: {data: templates, afterRender: makeDroppable } ">
<div class="card">
<div class="d-flex justify-content-between align-content-center">
<textarea rows="10" style="height: auto" aria-label="Content" class="txtDropTarget form-control m-3" aria-describedby="Template Content" data-bind="textInput: content"></textarea>
<div data-bind="html: content" class="m-3"></div>
</div>
<div class="d-flex justify-content-between align-content-center">
<ul class="dragList nav" data-bind="foreach: { data: $parent.tags, afterRender: $root.makeDraggable }">
<li data-bind="text: value" class="nav-item m-3 h5 move-pointer"></li>
</ul>
</div>
</div>
</div>
I'm designing a UI for editing and creating email template content using knockout.
I've implemented this:
I have a textarea and a preview div. when text is add in the text area it shows up in the preview area. under the textarea are acceptable tags which acts has placeholders. this placeholders will be replaced at runtime with actual values.
The problem I'm having right now is, If a tag is dragged into the textarea, the content observable is not updated immediately, I have to type in the text area to trigger an observable update.
<textarea rows="10" style="height: auto" aria-label="Content" class="txtDropTarget form-control m-3" aria-describedby="Template Content" data-bind="textInput: content"></textarea>
I've tried the textInput binding and valueUpdate: 'input' event, none of that worked

do this
$(this).insertAtCaret(ui.draggable.text()).change();
after drag.
I edited your example - https://jsfiddle.net/qskxzh0e/3/
self.makeDroppable = function(elements) {
$(".txtDropTarget").droppable({
accept: "li",
drop: function(ev, ui) {
$(this).insertAtCaret(ui.draggable.text()).change();
}
});
};

Related

How to set Check attribute for a radio element?

I'm trying to make a quiz app using JavaScript and jQuery, if I click on a radio button am setting an attribute as checked but if I move on to another question and click on any radio button there in the previous question radio button selects get removed how can I make sure that it is selected even if I move on to any question and select options there. I guess its happening because I have common name on the radio button Can someone help me out?
$(document).ready(function() {
$(function() {
var data = [{
"id": 1,
"question": "Which framework is best?",
"options": ["ReactJs", "AngularJs", "Vue.js", "Backbone"],
"correctanswer": "ReactJs",
"selectedanswer": ""
},
{
"id": 2,
"question": "What does MVC stands for?",
"options": ["Model View Controller", "Model view view Controller", "Model Controller view", "None of the above"],
"correctanswer": "Model View Controller",
"selectedanswer": ""
},
{
"id": 3,
"question": "Which is the best MOOC course website?",
"options": ["Coursera", "EDX", "Udacity", "Code School"],
"correctanswer": "Udacity",
"selectedanswer": ""
},
{
"id": 4,
"question": "which backend framework is not available in any of the MOOC site?",
"options": ["Ruby on Rails", "Node JS", "Metor Js", "Django"],
"correctanswer": "Django",
"selectedanswer": ""
},
{
"id": 5,
"question": "Which frontend framework is not available?",
"options": ["AngularJs", "ReactJs", "Backbone", "Knockout"],
"correctanswer": "ReactJs",
"selectedanswer": ""
}
];
var constructordata = function(data) {
this.id = data.id,
this.question = data.question,
this.options = data.options,
this.correctanswer = data.correctanswer,
this.selectedanswer = data.selectedanswer
};
var datas = [];
data.forEach(function(item) {
datas.push(new constructordata(item));
});
var controller = {
nextquestion: function() {
var currentelement = $('#app .questionsection.visible');
var nextelement = currentelement.next();
if (nextelement.hasClass('questionsection')) {
currentelement.removeClass('visible');
nextelement.addClass('visible');
}
if (!nextelement.next().hasClass('questionsection')) {
$("button").addClass('visible');
}
},
previousquestion: function() {
var currentelement = $('#app .questionsection.visible');
var previouselement = currentelement.prev();
if (previouselement.hasClass('questionsection')) {
currentelement.removeClass('visible');
previouselement.addClass('visible');
}
},
selectanswers: function(temp) {
for (var i = 0; i < datas.length; i++) {
if (datas[i].id == temp) {
datas[i].selectedanswer = $('input[name=optradio]:checked').val();
}
}
},
checkanswers: function() {
var score = 0;
datas.forEach(function(item) {
if (item.selectedanswer == item.correctanswer) {
score++;
}
});
console.log(score);
},
init: function() {
view.init();
}
};
var view = {
init: function() {
this.maintemplate = $("#app");
this.nextarrow = $("#next");
this.submit = $("button");
this.submit.on('click', function() {
controller.checkanswers();
})
this.nextarrow.on('click', function() {
controller.nextquestion();
});
this.previousarrow = $("#previous");
this.previousarrow.on('click', function() {
controller.previousquestion();
});
this.render();
},
render: function() {
var maintemplate = this.maintemplate;
for (var i = 0; i < datas.length; i++) {
maintemplate.append("<div class='questionsection'><p>" + datas[i].question + "</p></div>");
for (var j = 0; j < datas[i].options.length; j++) {
var options = "<div class='radio'><label><input type='radio' name='optradio' questionno=" + datas[i].id + " value=" + datas[i].options[j] + ">" + datas[i].options[j] + "</label></div>"
maintemplate.children('.questionsection').last().append(options);
}
}
maintemplate.children().first().addClass('visible');
var radio = $("input[name=optradio]");
radio.on('click', function() {
var temp = $(this).attr("questionno");
controller.selectanswers(temp);
$(this).attr("checked", "checked");
});
}
};
controller.init();
});
});
.questionsection {
display: none;
}
.btn {
display: none;
}
.visible {
display: block;
}
i.fa {
font-size: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-2">
<i id="previous" class="fa fa-arrow-left" aria-hidden="true"></i>
</div>
<div id="app" class="col-md-8">
</div>
<div class="col-md-2">
<i id="next" class="fa fa-arrow-right" aria-hidden="true"></i>
</div>
</div>
<button class="btn">Submit</button>
</div>
CodePen http://codepen.io/kannant14/pen/peLOXG
One way to solve it is to name your radiobuttons in the render function with a question index like:
var options="<div class='radio'><label><input type='radio' name='optradio"+i+"' questionno="+datas[i].id+" value="+datas[i].options[j]+">"+datas[i].options[j]+"</label></div>"
and the same in the selectanswers function:
selectanswers:function(temp) {
for(var i=0;i<datas.length;i++) {
if(datas[i].id==temp){
datas[i].selectedanswer=$('input[name=optradio'+i+']:checked').val();
}
}
}
then you just need to keep track of the question index when checking the correct answers.

Knockout bindings from JSON file

What am I doing wrong with my bindings? I simply get [object HTMLElement] returned for each one.
Please note this is a pared-down version and I will be wanting to access the full range of the JSON values.
Fiddle:
https://jsfiddle.net/0416f0s7/2/
Code:
<div data-bind="text: intro"></div>
function ViewModel(stories) {
var self = this;
self.stories = ko.observableArray(ko.utils.arrayMap(stories, function(story) {
return story.stories;
}));
};
$.getJSON('data.json', function(data) {
window.storyViewModel = new ViewModel(data.stories);
ko.applyBindings(window.storyViewModel);
});
JSON (filename data.json):
{
"stories": [
{
"intro": "Hi",
"outro": "Bye",
"elements": [
{
"title": "Title 1",
"image": "img/image1.jpg",
"paragraph": "Wordswordswords"
},
{
"title": "Title 2",
"image": "img/image2.jpg",
"paragraph": "More wordswordswords"
}
]
}
]
}
Your html change to
`<div data-bind="foreach:stories">
<div data-bind="text: intro"></div>
</div>
your code change to
function test(stories) {
var self = this;
self.stories = ko.observableArray(ko.utils.arrayMap(stories, function (story) {
return story;
}));
}

jQuery autocomplete suggests all options regardless of input entry

I have a jQuery script that will get a JSON response and create as many "player" objects as there are in the response.
It will then add to availablePlayers which I then use as the variable for the source: field of autocomplete
When a user selects a player name and clicks the "add" button it will, at the moment, just display the guid and name of a player.
However, no matter what letters I type, all the players are given as an option. To illustrate this, if I type "Z" and none of the players have Z in their name, they options are still displayed.
How can I refine this functionality?
HTML
<div class="player-widget">
<label for "players">Players</label>
<input id="player" />
<input id="playerGUID" hidden />
<button id="add">Add</button>
</div>
jQuery
$(document).ready(function(){
var availablePlayers = []; // BLANK ARRAY OF PLAYERS
$("#player").autocomplete({
source: availablePlayers,
response: function (event, ui) {
ui.content = $.map(ui.content, function(value, key) {
return {
label: value.name,
value: value.guid
}
});
},
focus: function(event, ui) {
$("#player").val(ui.item.label);
return false;
},
select: function (event, ui) {
$("#player").val(ui.item.label); // display the selected text
$("#playerGUID").val(ui.item.value); // save selected id to hidden input
return false;
}
});
$.getJSON("http://localhost/Websites/Player-Widgets/service.php", function(data) {
var feedHTML = '';
// LOOP THROUGH EACH PLAYER
$.each(data.players, function(i, player) {
// DEFINE VARIABLES - BASED ON PLAYER ATTRIBUTES
var guid = player.guid;
var name = player.name;
var dob = player.date_of_birth;
var birth = player.birthplace;
var height = player.height;
var weight = player.weight;
var position = player.position;
var honours = player.honours;
// CREATE NEW PLAYER (OBJECT)
var player = {
guid: guid,
name: name,
position: position
};
// ADD TO PLAYER TAG ARRAY
availablePlayers.push(player);
});
console.log("User friendly array");
$.each(availablePlayers, function(i, val) {
console.log(val.guid + " - " + val.name + " [" + val.position + "]");
});
console.log("Array printout");
console.log(JSON.stringify(availablePlayers));
}).done(function(){
console.log("Done! Success!");
$("#player").autocomplete("option", "source", availablePlayers);
});
$("#add").click(function() {
alert($("#playerGUID").val() + " - " + $("#player").val());
});
});
Sample JSON response
{
"players": [
{
"guid": "1",
"name": "Matias Aguero",
"date_of_birth": "1981-02-13",
"birthplace": "San Nicolas, Argentina",
"height": "1.83m (6' 0\")",
"weight": "109kg (17st 2lb)",
"position": "Prop",
"honours": "40 caps"
},
{
"guid": "2",
"name": "George Catchpole",
"date_of_birth": "1994-02-22",
"birthplace": "Norwich, England",
"height": "1.85em (6ft 1\")",
"weight": "104kg (16st 5lb)",
"position": "Centre",
"honours": ""
}
]
}
Your problem is in the source function.
Source function uses request to pass term param to query, and you are ignoring it.
If you're using availablePlayers to query, you should use
source: availablePlayers
and your current function to map {label, text} object in response parameter.
response: function (event, ui) {
ui.content = $.map(ui.content, function(value, key) {
return {
label: value.name,
value: value.guid
}
});
}

Kendo TreeView Search with Highlight

I have a KendoTreeview with spriteclass. I want to highlight the nodes (root as well as child nodes) with my search term. I have implemented the search functionality. But the issue when i search it is highlighting the term in the nodes but missing the SpriteClass in the nodes after first search. Any idea ?
jsFiddle code
$('#search-term').on('keyup', function () {
$('span.k-in > span.highlight').each(function () {
$(this).parent().text($(this).parent().text());
});
// ignore if no search term
if ($.trim($(this).val()) == '') {
return;
}
var term = this.value.toUpperCase();
var tlen = term.length;
$('#treeview-sprites span.k-in').each(function (index) {
var text = $(this).text();
var html = '';
var q = 0;
while ((p = text.toUpperCase().indexOf(term, q)) >= 0) {
html += text.substring(q, p) + '<span class="highlight">' + text.substr(p, tlen) + '</span>';
q = p + tlen;
}
if (q > 0) {
html += text.substring(q);
$(this).html(html);
$(this).parentsUntil('.k-treeview').filter('.k-item').each(
function (index, element) {
$('#treeview-sprites').data('kendoTreeView').expand($(this));
$(this).data('search-term', term);
});
}
});
$("#treeview-sprites").kendoTreeView({
dataSource: [{
text: "My Documents",
expanded: true,
spriteCssClass: "rootfolder",
items: [{
text: "Kendo UI Project",
expanded: true,
spriteCssClass: "folder",
items: [{
text: "about.html",
spriteCssClass: "html"
}, {
text: "index.html",
spriteCssClass: "html"
}, {
text: "logo.png",
spriteCssClass: "image"
}]
}, {
text: "New Web Site",
expanded: true,
spriteCssClass: "folder",
items: [{
text: "mockup.jpg",
spriteCssClass: "image"
}, {
text: "Research.pdf",
spriteCssClass: "pdf"
}, ]
}, {
text: "Reports",
expanded: true,
spriteCssClass: "folder",
items: [{
text: "February.pdf",
spriteCssClass: "pdf"
}, {
text: "March.pdf",
spriteCssClass: "pdf"
}, {
text: "April.pdf",
spriteCssClass: "pdf"
}]
}]
}]
})
;
Kendo's tree view widget doesn't like it if you muck around in its HTML, so I suggest modifying the data source instead (this will require the encoded option for all items in the DS).
In the keyup handler, you reset the DS whenever you search to clear highlighting, then instead of replacing the element's HTML directly, you set the model's text property:
$('#search-term').on('keyup', function () {
var treeView = $("#treeview-sprites").getKendoTreeView();
treeView.dataSource.data(pristine);
// ignore if no search term
if ($.trim($(this).val()) == '') {
return;
}
var term = this.value.toUpperCase();
var tlen = term.length;
$('#treeview-sprites span.k-in').each(function (index) {
var text = $(this).text();
var html = '';
var q = 0;
while ((p = text.toUpperCase().indexOf(term, q)) >= 0) {
html += text.substring(q, p) + '<span class="highlight">' + text.substr(p, tlen) + '</span>';
q = p + tlen;
}
if (q > 0) {
html += text.substring(q);
var dataItem = treeView.dataItem($(this));
dataItem.set("text", html);
$(this).parentsUntil('.k-treeview').filter('.k-item').each(
function (index, element) {
$('#treeview-sprites').data('kendoTreeView').expand($(this));
$(this).data('search-term', term);
});
}
});
$('#treeview-sprites .k-item').each(function () {
if ($(this).data('search-term') != term) {
$('#treeview-sprites').data('kendoTreeView').collapse($(this));
}
});
});
The tree definition needs the encoded option for this to work:
var pristine = [{
encoded: false,
text: "Kendo UI Project",
expanded: true,
spriteCssClass: "folder",
items: [{
encoded: false,
text: "about.html",
spriteCssClass: "html"
}, {
encoded: false,
text: "index.html",
spriteCssClass: "html"
}, {
encoded: false,
text: "logo.png",
spriteCssClass: "image"
}]
}, {
encoded: false,
text: "New Web Site",
expanded: true,
spriteCssClass: "folder",
items: [{
encoded: false,
text: "mockup.jpg",
spriteCssClass: "image"
}, {
encoded: false,
text: "Research.pdf",
spriteCssClass: "pdf"
}, ]
}, {
encoded: false,
text: "Reports",
expanded: true,
spriteCssClass: "folder",
items: [{
encoded: false,
text: "February.pdf",
spriteCssClass: "pdf"
}, {
encoded: false,
text: "March.pdf",
spriteCssClass: "pdf"
}, {
encoded: false,
text: "April.pdf",
spriteCssClass: "pdf"
}]
}];
$("#treeview-sprites").kendoTreeView({
dataSource: [{
text: "My Documents",
expanded: true,
spriteCssClass: "rootfolder",
items: pristine
}]
});
(demo)
Good job guys, just what I neeeded!
Using your code I did a small tweak (actually added just two lines of jquery filtering), so that now when searching for a keyword, the treeview shows only the branches that contain highlighted texts. Easy peasy! :)
Other branches are hidden if they do not contain the higlighted text. Simple as that.
This means we now have a VisualStudio-like treeview search (see the Visual Studio Solution Explorer Search and Filter: http://goo.gl/qr7yVb).
Here's my code and demo on jsfiddle: http://jsfiddle.net/ComboFusion/d0qespaz/2/
HTML:
<input id="treeViewSearchInput"></input>
<ul id="treeview">
<li data-expanded="true">My Web Site
<ul>
<li data-expanded="true">images
<ul>
<li>logo.png</li>
<li>body-back.png</li>
<li>my-photo.jpg</li>
</ul>
</li>
<li data-expanded="true">resources
<ul>
<li data-expanded="true">pdf
<ul>
<li>brochure.pdf</li>
<li>prices.pdf</li>
</ul>
</li>
<li>zip</li>
</ul>
</li>
<li>about.html</li>
<li>contacts.html</li>
<li>index.html</li>
<li>portfolio.html</li>
</ul>
</li>
<li>Another Root</li>
</ul>
CSS
span.k-in > span.highlight {
background: #7EA700;
color: #ffffff;
border: 1px solid green;
padding: 1px;
}
JAVASCRIPT
function InitSearch(treeViewId, searchInputId) {
var tv = $(treeViewId).data('kendoTreeView');
$(searchInputId).on('keyup', function () {
$(treeViewId + ' li.k-item').show();
$('span.k-in > span.highlight').each(function () {
$(this).parent().text($(this).parent().text());
});
// ignore if no search term
if ($.trim($(this).val()) === '') {
return;
}
var term = this.value.toUpperCase();
var tlen = term.length;
$(treeViewId + ' span.k-in').each(function (index) {
var text = $(this).text();
var html = '';
var q = 0;
var p;
while ((p = text.toUpperCase().indexOf(term, q)) >= 0) {
html += text.substring(q, p) + '<span class="highlight">' + text.substr(p, tlen) + '</span>';
q = p + tlen;
}
if (q > 0) {
html += text.substring(q);
$(this).html(html);
$(this).parentsUntil('.k-treeview').filter('.k-item').each(function (index, element) {
tv.expand($(this));
$(this).data('SearchTerm', term);
});
}
});
$(treeViewId + ' li.k-item:not(:has(".highlight"))').hide();
$(treeViewId + ' li.k-item').expand(".k-item");
});
}
var $tv = $("#treeview").kendoTreeView();
InitSearch("#treeview", "#treeViewSearchInput");
Another tweak from me :)
What I did was change the highlight code in order to preserve anything else that might exist in the node html (such as sprite span for example).
I also implemented it as a TypeScript class wrapper around the TreeView.
If you don't want TypeScript stuff just copy the code out and it should work fine :)
export class SearchableTreeView {
TreeView: kendo.ui.TreeView;
emphasisClass: string;
constructor(treeView: kendo.ui.TreeView) {
this.TreeView = treeView;
this.emphasisClass = "bg-warning";
}
search(term: string): void {
var treeElement: JQuery = this.TreeView.element;
var tv: kendo.ui.TreeView = this.TreeView;
var emphClass = this.emphasisClass;
this.resetHighlights();
// ignore if no search term
if ($.trim(term) === '') { return; }
var term = term.toUpperCase();
var tlen = term.length;
$('span.k-in', treeElement).each(function (index) {
// find all corresponding nodes
var node = $(this);
var htmlContent = node.html();
var text = node.text();
var searchPosition = text.toUpperCase().indexOf(term);
if (searchPosition === -1) {
// continue
return true;
}
var generatedHtml = '<span class="highlight-container">' + text.substr(0, searchPosition) + '<span class="' + emphClass + '">' + text.substr(searchPosition, tlen) + '</span>' + text.substr(searchPosition + tlen) + '</span>';
htmlContent = htmlContent.replace(text, generatedHtml);
node.html(htmlContent);
node.parentsUntil('.k-treeview').filter('.k-item').each(
function (index, element) {
tv.expand($(this));
$(this).data('search-term', term);
}
);
});
$('.k-item', treeElement).each(function () {
if ($(this).data('search-term') != term) {
tv.collapse($(this));
}
});
}
resetHighlights(): void {
this.TreeView.element.find("span.k-in:has('." + this.emphasisClass + "')")
.each(function () {
var node = $(this);
var text = node.text();
$(".highlight-container", node).remove();
node.append(text);
});
}
}
$("#textBox").on("input", function () {
var query = this.value.toLowerCase();
var dataSource = $("#Treeview").data("kendoTreeView").dataSource;
filter(dataSource, query);
});
function filter(dataSource, query) {
var uidData = [];
var data = dataSource instanceof kendo.data.DataSource && dataSource.data();
for (var i = 0; i < data.length; i++) {
var item = data[i];
var text = item.text.toLowerCase();
var isChecked = item.checked;
var itemVisible =
query === true
|| query === ""
|| text.indexOf(query) >= 0;
uidData.push({ UID: item.uid, Visible: itemVisible });
}
if (query != "") {
$.each(uidData, function (index, datavalue) {
if (datavalue.Visible) {
$("li[data-uid='" + datavalue.UID + "']").addClass("highlight");
}
else {
$("li[data-uid='" + datavalue.UID + "']").removeClass("highlight");
}
});
}
else {
$.each(uidData, function (index, datavalue) {
$("li[data-uid='" + datavalue.UID + "']").removeClass("highlight");
});
}
}
CSS :
.highlight {
background:#0fa1ba;
color:white;
}
For Angular 2+ you need to create a pipe for this feature.
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
import { NGXLogger } from 'ngx-logger';
#Pipe({
name: 'highlight'
})
export class TypeaheadHighlight implements PipeTransform {
constructor(private readonly _sanitizer: DomSanitizer, private readonly logger: NGXLogger) { }
transform(matchItem: any, query: any): string {
let matchedItem: any;
if (matchItem) {
matchedItem = matchItem.toString();
}
if (this.containsHtml(matchedItem)) {
this.logger.warn('Unsafe use of typeahead please use ngSanitize');
}
matchedItem = query ? ('' + matchedItem).replace(new RegExp(this.escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchedItem; // Replaces the capture string with a the same string inside of a "strong" tag
if (!this._sanitizer) {
matchedItem = this._sanitizer.bypassSecurityTrustHtml(matchedItem);
}
return matchedItem;
}
escapeRegexp = (queryToEscape) => queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
containsHtml = (matchItem) => /<.*>/g.test(matchItem);
}
Use of this pipe in html template....
<input name="searchTerm" type="text" [(ngModel)]="searchTerm" (keyup)='onkeyup(searchTerm)'
/>
</div>
<div style="height: 70vh;overflow: auto">
<kendo-treeview style="margin-top: 50px" id="availableColumns" [nodes]="availableColumns"
textField="displayName" kendoTreeViewExpandable kendoTreeViewFlatDataBinding idField="id"
parentIdField="parentId">
<ng-template kendoTreeViewNodeTemplate let-dataItem>
<span [tooltip]="dataItem.columnDescription"
[innerHtml]="dataItem.displayName | highlight:searchTerm "></span>
</ng-template>
</kendo-treeview>
</div>

Kendo Grid with Kendo Dropdownlist Selected value not updated

In my kendo grid, i have kendodropdownlist for each column. A selected item should resolve and also show the template text
i have been following the example here http://jsfiddle.net/jddevight/Ms3nn/
UPDATE
I have simplified my issue in here http://jsfiddle.net/BlowMan/mf434/
Problem
When i select a an item in the dropdown, it does not return the value of the selected item. It rather returns null.
/// <reference path="../../jquery-1.8.2.js" />
/// <reference path="../../kendo.web.min.js" />
$(function () {
var menuModel = kendo.data.Model.define({
fields: {
"MenuId": { type: "number",editable:false },
"DisplayText":{type:"string"},
"MenuOrder": { type: "number" },
"MenuStatus": { type: "boolean" },
"HasKids": { type: "boolean" },
"ParentMenu": { type: "number" }
}
});
var menuDataSource = new kendo.data.DataSource({
data:[{"MenuId":1,
"DisplayText":"Home",
"MenuOrder":0,
"MenuStatus":true,
"HasKids":false,
"ParentMenu":null},
{"MenuId":2,
"DisplayText":"Finance",
"MenuOrder":1,
"MenuStatus":true,
"HasKids":false,
"ParentMenu":null}]
schema: {
model: menuModel
}
});
var vm = kendo.observable({
menus: menuDataSource,
parentItem: [{ Id: 2,
Name: "Finance" },
{ Id: 3,
Name: "Corp Services" }],
getMenuName: function (pMenu) {
var menuName = "";
$.each(this.parentItem, function (idx, menu) {
if (menu.Id == pMenu) {
menuName = menu.Name;
return false;
}
});
return menuName;
}
});
kendo.bind($("#menuItems"), vm);
var parentMenuEditor = function (container, options) {
$("<input name='" + options.field + "'/>")
.appendTo(container)
.kendoDropDownList({
dataSource: {
data:[{ Id: 2, Name: "Finance" }, { Id: 3, Name: "Corp Services" }],
},
dataTextField: "Name",
dataValueField: "Id"
});
};
var grid = $("div[data-role='grid']").data("kendoGrid");
$.each(grid.columns, function (idx, column) {
if (column.field == "ParentMenu") {
column.editor = parentMenuEditor;
return false;
}
});
});
The view section below
#{
ViewBag.Title = "Menu System Index";
}
<h2>Menu System Index</h2>
<div id="menuItems">
<div class="k-toolbar k-grid-toolbar">
<a class="k-button k-button-icontext k-grid-add" href="#">
<span class="k-icon k-add"></span>
Add Person
</a>
</div>
<div data-role="grid"
data-bind="source: menus"
data-editable="true"
data-filterable="true"
data-columns='[{"field": "MenuId", "title": "MenuId"},
{"field": "DisplayText", "title": "DisplayText"},
{"field": "MenuOrder", "title": "MenuOrder"},
{"field": "MenuStatus", "title": "MenuStatus"},
{"field":"HasKids","title":"HasKids"},
{"field":"ParentMenu","title":"ParentMenu","template":"#= parent().parent().getMenuName(ParentMenu) #"},
{"command": "destroy", "title": " ", "width": "110px"}]'>
</div>
</div>
<script type="text/x-kendo-template" id="toolbar-template">
<a class="k-button k-button-icontext k-grid-add" href="\#"><span class="k-icon k-add"></span>Add new record</a>
</script>
#section scripts{
<script src="~/Scripts/Custom/MenuSystem/Index.js"></script>
}
Any assistance will be much appreciated. This problem has me on my knees.
I have updated your JsFiddle demo. Please check it and let me know if any concern.
var roleEditor = function(container, options) {
$("<input name='" + options.field + "' data-text-field='name' data-value-field='id' data-bind='value:" + options.field + "'/>")
.appendTo(container)
.kendoDropDownList({
dataSource: {
data: vm.roles
},
dataTextField: "name",
dataValueField: "id"
});
};

Categories