I have small knowledge of JS, but I was assigned a task to add some functionality to page. I need to add a datepicker in birthDate field, but once I add datepicker function to page my, validation(Jquery validation) stop working.
Here is code:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# page session="false"%>
<%# taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://jqueryvalidation.org/files/demo/site- demos.css" />
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"> </script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<title>Parent Registration</title>
</head>
<body>
<!-- Everything inside should be the body -->
<tiles:insertDefinition name="defaultTemplate">
<tiles:putAttribute name="body">
....some code.........
<div class="form-group" >
<label for="birthDate" class="col-sm-3 control-label">Birthday</label>
<div class="col-sm-6">
<form:input type="text" class="form-control float_left" id="birthDate" name="birthDate" path="birthDate" placeholder="MM/DD/YYYY" required="true" />
</div>
</div>
...........some code...........
<script src="/resources/js/jquery.validate.min.js"></script>
<script src="/resources/js/validation.js"></script>
<script>
jQuery.validator.addMethod(
"dateUS",
function(value, element) {
var check = false;
var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
if( re.test(value)){
var adata = value.split('/');
var mm = parseInt(adata[0],10);
var dd = parseInt(adata[1],10);
var yyyy = parseInt(adata[2],10);
var xdata = new Date(yyyy,mm-1,dd);
var currentTime = new Date();
var year = currentTime.getFullYear();
if ( ( xdata.getFullYear() == yyyy) && ( xdata.getFullYear() <= year ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == dd ) )
check = true;
else
check = false;
} else
check = false;
return this.optional(element) || check;
},
"Please enter a date in the format MM/DD/YYYY"
);
jQuery.validator.addMethod("parentName", function(value, element) {
return this.optional( element ) || /^(?=.*[a-zA-Z])([a-zA-Z.'-\s]+)$/.test( value );
}, 'The name should contain at least one alphabet character, space, dot, hyphen, apostrophe.');
$(document).ready(function(){
jQuery.validator.setDefaults({
debug: true,
success: "valid"
});
$("#myform").validate({
rules: {
firstName: {
required: true,
parentName: true
},
middleName: {
parentName: true
},
lastName: {
required: true,
parentName: true
},
noOfChildren: {
required: true,
digits: true
},
birthDate: {
required: true,
dateUS: true
},
email: {
required: true,
email:true
},
confirmemail: {
required: true,
equalTo: "#email"
},
confirmpassword: {
required: true,
equalTo: "#password"
}
},
errorPlacement: function (label, element) {
if(element.is("input:checkbox")) {
element.parent("label").after( label );
} else if(element.is("input:radio")){
element.parent("label" ).parent("div:first").after( label );
}
else {
label.insertAfter( element );
}
},
submitHandler: function(form) {
form.submit();
}
});
});
</script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function() {
$( "#birthDate" ).datepicker();
});
</script>
</tiles:putAttribute>
</tiles:insertDefinition>
</body>
</html>
You are including jquery 1.10.2 (at the bottom) and 1.11.3 (top) javascript files. This is most likely the problem.
Tipp: In Firefox you can debug your javascript and see error messages by pressing Ctrl+Shift+K or through Extras->Web-Developer->Web-Console.
Related
I'm creating web application with zTree.
The tree is built based on data from the Golang backend.
Tree leaves change custom icons while the application is running.
How to change icons, based on backend data, without refreshing the page?
With http-equiv="refresh" page is blinking and lost focus. Here is working but blinking sample with zTree and refresh (I cut of backend part for simplicity):
<HTML>
<HEAD>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="refresh" content="5">
<link rel="stylesheet" href="../static/css/zTreeStyle/zTreeStyle.css" type="text/css">
<script type="text/javascript" src="../static/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../static/js/jquery.ztree.core.js"></script>
</HEAD>
<BODY>
<div id="app">
<TABLE>
<TR>
<TD width=260px valign=top>
<ul id="tree" class="ztree"></ul>
</TD>
<TD valign=top>
<p>Some text</p>
</TD>
</TR>
</TABLE>
<SCRIPT type="text/javascript">
var zTree;
var setting = {
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pId",
rootPId: ""
}
}
};
var zNodes = [
{id: 1, pId: 0, name: "root", icon:"../static/css/zTreeStyle/img/diy/c16green.png"},
{id: 2, pId: 1, name: "leaf", icon:"../static/css/zTreeStyle/img/diy/c16red.png"},
];
$(document).ready(function () {
var t = $("#tree");
t = $.fn.zTree.init(t, setting, zNodes);
});
</script>
</div>
</BODY>
</HTML>
I try to use Vue.js, but cannot bind data to zTree. Here is not working sample with Vue.js data binding inside script tag:
<HTML>
<HEAD>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../static/css/zTreeStyle/zTreeStyle.css" type="text/css">
<script type="text/javascript" src="../static/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../static/js/jquery.ztree.core.js"></script>
<script src="https://unpkg.com/vue"></script>
</HEAD>
<BODY>
<div id="app">
<TABLE>
<TR>
<TD width=260px valign=top>
<ul id="tree" class="ztree"></ul>
</TD>
<TD valign=top>
<p>{{ now }}</p>
<p>Some text</p>
</TD>
</TR>
</TABLE>
<SCRIPT type="text/javascript">
var zTree;
var setting = {
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pId",
rootPId: ""
}
}
};
var zNodes = [
{id: 1, pId: 0, name: "root", icon:"../static/css/zTreeStyle/img/diy/c16green.png"},
{id: 2, pId: 1, name: "leaf", icon:"../static/css/zTreeStyle/img/diy/c16red.png"},
{id: 3, pId: 1, name: "foo", icon: {{ customIcon }} },
];
$(document).ready(function () {
var t = $("#tree");
t = $.fn.zTree.init(t, setting, zNodes);
});
const app = new Vue({
el: '#app',
data: {
now: new Date(),
customIcon : "../static/css/zTreeStyle/img/diy/c16green.png"
},
methods: {
updateDate() {
this.now = new Date();
}
},
mounted() {
setInterval(() => {
this.updateDate();
}, 1000);
},
})
</script>
</div>
</BODY>
</HTML>
Zipped sample (examples are inside template directory): https://drive.google.com/file/d/1Ihv8jLdsEz93aUrFjEugD1l6YvslaUT8
The solution contains a few steps:
use "go-echo-vue" for communication between backend and frontend like here: https://github.com/covrom/go-echo-vue
update zTree data using vue-resource and timer like this:
<script>
new Vue({
// ....
methods: {
updateZNodes() {
// запрашиваем дерево :)
this.$http.get('/znodes').then(function (response) {
zNodes = response.data.items ? response.data.items : []
}, function (error) {
console.log(error)
});
},
},
mounted() {
setInterval(() => {
this.updateZNodes();
}, 5000);
},
// ....
})</script>
refrest zTree nodes information using js:
<script language="JavaScript">
function refreshNode() {
var treeObj = $.fn.zTree.getZTreeObj("tree");
var nodes = treeObj.getNodes();
if (nodes.length > 0) {
for (let i = 0; i < nodes.length; i++) {
c = "static/css/zTreeStyle/img/diy/c16grey.png";
if (zNodes.length >= i) {
c = zNodes[i].icon
}
nodes[i].icon = c;
treeObj.updateNode(nodes[i]);
}
}
};
const timerId = setInterval(
() => {
refreshNode();
},
5000
);
</script>
add async zTree settings:
<script language="JavaScript">
var setting = {
// ....
async: {
enable: true,
url: "",
autoparam: ["id", "icon"],
datatype: "json",
},
// ....
};
</script>
That's all. So we have Vue function http.get to get fresh data from backend, global js variable to use that data both inside Vue code segment and JavaScript blocks.
PS additional information: https://www.tutorialfor.com/blog-188266.htm
That's my whole test file. I've done so far, validation and it changes span class correctly due to correctly or not correctly fulfilled input. But where I'm stuck is I want disable button if there is not correctly fulfilled input or empty at all. And I think I've done logic right, but it doesn't work. I consoled.loged it, I see where is an issue, but why it happens for me is a mystery.
In short what happens: button is signed to variable button, and inputs on every input event calling function ft_button which check's if inputs are correctly fulfilled and buy that result it changes variable button. And it would have been fine, but in this function I don't know why it runs forEach cycle 5 times when there is return written. Is it some sort of JS thing? Cause in C if there is a return it stopps looping no matter what. And of course it will print out active at the end since it just skips all returns in forEach loop.
on pic you can see it logs 5 times 2 which is actually a surprise for me, cause after return it should just stop looping. Gmm how then should I return active or disabled...
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/font-awesome.min.css">
<link href="css/styles.css" rel="stylesheet">
<script src="js/vue.js"></script>
</head>
<body>
<div class="wrapper">
<div class="sample">
<form>
<div class="progress">
<div class="progress-bar"></div>
</div>
<div>
<div class="form-group" v-for="v in info">
<label v-bind:for='v.name'>{{ v.name | capitalize }}</label><span :class="alertType(v.value)"></span>
<input id="intra" type="text" class="form-control" v-on:input="checkInput($event, v)">
<div>{{ v.value ? 'true' : 'false'}}</div>
</div>
</div>
<button class="btn btn-primary" :class="button">
Send Data
</button>
</form>
<div>
<table class="table table-bordered">
<tr>
<td></td>
<td></td>
</tr>
</table>
</div>
</div>
</div>
<script>
Vue.filter('capitalize', function (value) {
if (!value) return '';
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
el: '.sample',
data: {
button: 'disabled',
info: [
{
name: 'intra',
value: '',
pattern: /^[a-zA-Z ]{2,30}$/
},
{
name: 'phone',
value: '',
pattern: /^[0-9]{7,14}$/
},
{
name: 'email',
value: '',
pattern: /.+/
},
{
name: 'password',
value: '',
pattern: /.+/
},
{
name: 'repeatPassword',
value: '',
pattern: /.+/
}
]
},
methods:
{
checkInput(e, obj){
obj.value = obj.pattern.test(e.target.value);
this.button = this.ft_button();
},
alertType(value)
{
if(value === true)
return "fa fa-check-circle";
if(value === false)
return "fa fa-exclamation-circle";
},
ft_button()
{
this.info.forEach((el) =>
{
if (el.value === false || el.value === '')
{
console.log(2);
return 'disabled';
}
})
console.log(1);
return 'active';
}
},
computed:
{
}
});
</script>
</body>
</html>
you can't return from forEach the same way you can in a vanilla for loop. This question may be helpful: What does `return` keyword mean inside `forEach` function?
I have a project where I need to count the number of misspelled words in a text area and prevent submission of the web form if there are too many misspellings. The JavaScript editor, tinyMCE is used for the entry form. A PHP script, spellcheckText.php, counts the misspellings, if any, and returns a JSON encoded result back to the brows. Code example below:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<link rel="stylesheet" src="/simages/css/bootstrap/3.3.7/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/simages/scripts/js/tinymce/js/tinymce/tinymce.min.js"></script>
<script>
tinymce.init({
selector: ".standard-editor",
plugins: "wordcount spellchecker",
paste_as_text: false,
theme: "modern",
branding: false,
content_style: ".mce-content-body {font-size:16px;font-family:Arial,sans-serif;}",
browser_spellcheck: true,
toolbar: "undo redo",
spellchecker_rpc_url: '/simages/spellchecker/spellchecker.php',
menubar: "tools",
statusbar: true,
height: "400",
width: "600",
paste_data_images: false,
paste_enable_default_filters: false,
paste_preprocess: function(plugin, args) {
args.content = '';
}
});
</script>
<script type="text/javascript">
function checkWordCount() {
var wordCount = tinyMCE.activeEditor.plugins["wordcount"].getCount();
if (wordCount < 50) {
alert("Need 50 words or greater for your text submission...");
return false;
}
var essayContent = tinyMCE.activeEditor.getContent({format: 'text'});
function getSpellCount(essayContent){
return new Promise((resolve,reject) => {
jQuery(function(\$) {
var values = { 'str': essayContent };
\$.ajax({
type: "POST",
url: "/path/to/spellcheckEssay.php",
data: values,
success: resolve,
error: reject,
})
});
})
}
var percentage = getSpellCount(essayContent);
percentage.then(function(result){
console.log(result);
var grade = result.percentage;
if(grade < 80){
alert("Please edit your response.");
return false;
}else{
document.essayform.submit();
}
}).catch(function (error) {
console.log('Failed',error);
});
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="form-group">
<form method=POST action="/path/to/ajax/textWords.php" name="essayform" id="essayQuestion" onsubmit="event.preventDefault();checkWordCount();">
<h3>$thesequestions{'Text'}</h3>
<p>
<textarea name="textarea" class="standard-editor" id="essay"></textarea>
</p>
<br/>
<input class="btn btn-primary" type="submit" value="Submit Text"/>
</form>
</div>
</div>
</body>
</html>```
I don't do front end coding that often, so don't know if the attempt to post twice in the same form is the problem or something else. Results of this example is a blank page where form's post action is executed. Don't believe that jQuery section is executed.
Open to suggestions for a better method.
Thank you.
**Below is a revision of the original code post**:
```<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<link rel="stylesheet" src="/css/bootstrap/3.3.7/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/scripts/js/tinymce/js/tinymce/tinymce.min.js"></script>
<script>
tinymce.init({
selector: ".standard-editor",
plugins: "wordcount spellchecker",
paste_as_text: false,
theme: "modern",
branding: false,
content_style: ".mce-content-body {font-size:16px;font-family:Arial,sans-serif;}",
browser_spellcheck: true,
toolbar: "undo redo",
spellchecker_rpc_url: '/simages/spellchecker/spellchecker.php',
menubar: "tools",
statusbar: true,
height: "400",
width: "600",
paste_data_images: false,
paste_enable_default_filters: false,
paste_preprocess: function(plugin, args) {
args.content = '';
}
});
</script>
<script type="text/javascript">
function checkWordCount() {
var wordCount = tinyMCE.activeEditor.plugins["wordcount"].getCount();
if (wordCount < 50) {
alert("Need 50 words or greater for your text submission...");
return false;
}
var essayContent = tinyMCE.activeEditor.getContent({format: 'text'});
function getSpellCount(essayContent){
return new Promise((resolve,reject) => {
jQuery(function($) {
var values = { 'str': essayContent };
console.log(values);
$.ajax({
type: "POST",
url: "/path/to/ajax/spellcheckText.php",
data: values,
success: resolve,
error: reject,
})
});
})
}
var percentage = getSpellCount(essayContent);
percentage.then(function(result){
console.log(result);
var grade = result.percentage;
if(grade < 80){
alert("A number of misspelled words were detected. Please correct and submit again.");
return false;
}
}).catch(function (error) {
console.log('Failed',error);
});
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="form-group">
<form method=POST action="/path/to/ajax/textWords.php" name="essayform" id="essayQuestion" onsubmit="event.preventDefault();checkWordCount();">
<h3>$thesequestions{'Text'}</h3>
<p>
<textarea name="textarea" class="standard-editor" id="essay"></textarea>
</p>
<br/>
<input class="btn btn-primary" type="submit" value="Submit Text"/>
</form>
</div>
</div>
</body>
</html>```
Below is the revised code. The path to the solution was pointed out by Taplar where I was returning false incorrectly. Also accessing the tinyMCE data correctly helps make things work.
```<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<link rel="stylesheet" src="/simages/css/bootstrap/3.3.7/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/scripts/js/tinymce/js/tinymce/tinymce.min.js"></script>
<script>
tinymce.init({
selector: ".standard-editor",
plugins: "wordcount spellchecker",
paste_as_text: false,
theme: "modern",
branding: false,
content_style: ".mce-content-body {font-size:16px;font-family:Arial,sans-serif;}",
browser_spellcheck: true,
toolbar: "undo redo",
spellchecker_rpc_url: '/path/to/spellchecker/spellchecker.php',
menubar: "tools",
statusbar: true,
height: "400",
width: "600",
paste_data_images: false,
paste_enable_default_filters: false,
paste_preprocess: function(plugin, args) {
args.content = '';
}
});
</script>
<script type="text/javascript">
function checkWordCount() {
var wordCount = tinyMCE.activeEditor.plugins["wordcount"].getCount();
if (wordCount < 50) {
alert("Need 50 words or greater for your text submission...");
return false;
}
var essayContent = tinyMCE.activeEditor.getContent({format: 'text'});
function getSpellCount(essayContent){
return new Promise((resolve,reject) => {
jQuery(function($) {
var values = { 'str': essayContent };
console.log(values);
$.ajax({
type: "POST",
url: "/path/to/ajax/spellcheckText.php",
data: values,
success: resolve,
error: reject,
})
});
})
}
var percentage = getSpellCount(essayContent);
percentage.then(function(result){
console.log(result);
var grade = result.percentage;
if(grade < 80){
alert("A number of misspelled words were detected. Please correct and submit again.");
return false;
}
}).catch(function (error) {
console.log('Failed',error);
});
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="form-group">
<form method=POST action="/path/to/ajax/textWords.php" name="essayform" id="essayQuestion" onsubmit="event.preventDefault();checkWordCount();">
<h3>$thesequestions{'text'}</h3>
<p>
<textarea name="textarea" class="standard-editor" id="essay"></textarea>
</p>
<br/>
<input class="btn btn-primary" type="submit" value="Submit Text"/>
</form>
</div>
</div>
</body>
</html>```
I am using the autocomplete to search the query.
In this source code, if you input ac you can get accepts, action_name.
However, I would like to get action_name with input name as a normal search form.
How can I make it?
$(function() {
var data = [
'accepts',
'action_name',
'add',
'add_column',
'add_index',
'add_timestamps',
'after_create',
];
$('#txtKeywd').autocomplete({
source: function(request, response) {
response(
$.grep(data, function(value){
return value.indexOf(request.term) === 0;
})
);
},
autoFocus: true,
delay: 500,
minLength: 2
});
});
$(function() {
var availableTags = [
'accepts',
'action_name',
'add',
'add_column',
'add_index',
'add_timestamps',
'after_create',
];
$("#tags").autocomplete({
source: availableTags
});
});
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
If you want to use the autocomplete plugin this will do it:
$(document).ready(function () {
var data = [
'accepts',
'action_name',
'add',
'add_column',
'add_index',
'add_timestamps',
'after_create',
];
$('#txtKeywd').autocomplete({
source: function(request, response) {
var re = $.ui.autocomplete.escapeRegex(request.term);
var matcher = new RegExp( re, "i" );
var a = $.grep( data, function(item,index){
return matcher.test(item);
});
response( a );
},
autoFocus: true,
delay: 500,
minLength: 2
});
});
You need to override the default regex used for autocomplete.
1 . Instead of just checking if the value is in the data element you can split the data element by - and _.
value.split(/-|_/)
2 . Then loop through it with a forEach() which takes as a parameter a function. e is the data element's value.
value.split(/-|_/).forEach(function(e) {});
3 . Then we just check if the input is in the e string
if(e.indexOf(request.term) === 0) {}
4 . If true and only if true we need to tell the grep() we're in that we have a successful match. To do so we need to set a boolean.
if(e.indexOf(request.term) === 0) { isIn = true; return; }
Above return; will end the search in the current split data element.
Here is the full code:
$(function() {
var data = [
'accepts',
'action_name',
'add',
'add_column',
'add_index',
'add_timestamps',
'after_create',
];
$('#tags').autocomplete({
source: function(request, response) {
response(
$.grep(data, function(value) {
let isIn;
value.split(/-|_/).forEach(function(e) {
if(e.indexOf(request.term) === 0) { isIn = true; return; }
});
return isIn
})
);
},
autoFocus: true,
delay: 500,
minLength: 2
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
Of course, this can be improved by splitting all the data values once on page load and store them in a special array to check.
Check this out
var data = [
'accepts',
'action_name',
'add',
'add_column',
'add_index',
'add_timestamps',
'after_create',
];
function split(val) {
return val.split(/ \s*/);
}
function extractLast(term) {
return split(term).pop();
}
$("#opt")
.autocomplete({
minLength: 0,
source: function(request, response) {
var term = request.term,
results = [];
term = extractLast(request.term);
if (term.length > 0) {
results = $.ui.autocomplete.filter(data, term);
}
response(results);
},
focus: function() {
return false; // prevent value inserted on focus
},
select: function(event, ui) {
}
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="ui-widget">
<label for="opt">Type Here:</label><br/>
<input id="opt" size="50">
</div>
I have a Kendo model instance (person for this example) and watching it is modified or not by using dirty property.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo + Angular</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl">
<div>Person name: {{ person.name }}</div>
<input type="text" name="name" ng-model="person.name"> <!-- This input don't work -->
<button ng-click="foo()">Foo</button> <!-- This button work because I call person.set method manually -->
<div>This person is modified? {{ person.dirty }}</div>
</div>
<script>
var Person = kendo.data.Model.define({
id: "personId", // the identifier of the model
fields: {
"name": {
type: "string"
},
"age": {
type: "number"
}
}
});
angular.module("app", ["kendo.directives"])
.controller("MainCtrl", function ($scope) {
$scope.person = new Person({
name: "John Doe",
age: 42
});
$scope.foo = function () {
$scope.person.set('name', "Kendo");
}
});
</script>
</body>
</html>
But when I type to text box dirty don't change because Angular ngModel doesn't fire Kendo "change" event. My real app have dozens of models like this, so is there any way to fix this automatically???
Thanks.
You can write a directive to replace for ng-model,
<input type="text" name="name" k-bind-model="person.name">
angular.module('app')
.directive("kBindModel", ["$parse", function ($parse) {
return {
restrict: "A",
scope: false,
link: function (scope, element, attributes, controller) {
var key = null;
var strs = attributes.kBindModel.split('.');
if (strs && strs.length > 1) {
key = strs[1];
}
var model = scope[strs[0]];
element.change(function () {
scope.$apply(function () {
model.set(key, element.val());
});
});
scope.$watch(attributes.kBindModel, function (n, o) {
element.val(n);
});
}
}
}]);