Related
How to handle events on jQuery dialog box. For example I want to handle onchange event on jQuery dialog.
Can anyone suggest on the same
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js" type="text/javascript"></script>
<style type="text/css">
label, input {
display: block;
}
input.text {
margin-bottom: 12px;
width: 95%;
padding: .4em;
}
fieldset {
padding: 0;
border: 0;
margin-top: 25px;
}
h1 {
font-size: 1.2em;
margin: .6em 0;
}
div#users-contain {
width: 350px;
margin: 20px 0;
}
div#users-contain table {
margin: 1em 0;
border-collapse: collapse;
width: 150%;
}
div#users-contain table td, div#users-contain table th {
border: 1px solid #eee;
padding: .6em 10px;
text-align: left;
}
.ui-dialog .ui-state-error {
padding: .3em;
}
.validateTips {
border: 1px solid transparent;
padding: 0.3em;
}
#dialog-form {
display: none;
}
#button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
top: 1000px;
}
#buttondisplay {
background-color: black;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
top: 1000px;
}
#buttonadd {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
top: 1000px;
}
#buttondisplay1 {
background-color: black;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
top: 1000px;
}
#buttonadd1 {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
top: 1000px;
}
#first {
border: 2px solid;
top: 500px;
padding: 12px;
background: #F8F9F9;
width: 1200px;
position: absolute;
right: 150px;
}
#firstinfo {
border: 2px solid;
top: 29px;
padding: 12px;
background: #F8F9F9;
width: 1200px;
position: absolute;
right: 150px;
}
#headerlogo {
height: 70px;
background: #0f2d51;
}
#headerlogo1 {
height: 70px;
background: #0f2d51;
}
#centername {
position: absolute;
top: 3px;
padding: 12px;
font-family: verdana;
}
#centername1 {
position: absolute;
font-family: verdana;
top: 3px;
padding: 12px;
right:290px;
}
</style>
</head>
<script type="text/javascript">
var myarr=[];
var finalarr=[];
var infopanelarr=[];
var datagridarray=[];
var switchflag=0;
var datapropertyoptions="";
var entitiyoptions ="";
var projectoptions ="";
var moduleoptions ="";
var datapropertyoptions="";
var projects=[];
var modules=[];
var entity=[];
var projectid=0;
var moduleid=0;
function resetpage() {
location.reload();
loaddetails();
}
function lowercase(value) {
var value = value.replace(/\s+/g, '');
return value.toLowerCase();
}
function upperCamelCase(value) {
var valuearr = value.split(" ");
var val="";
for(var i =0; i < valuearr.length; i++){
val = val + capitalFirstLetter(valuearr[i]);
}
return val;
}
function lowerCamelCase(value) {
var valuearr = value.split(" ");
var val=valuearr[0].toLowerCase();
for(var i =1; i < valuearr.length; i++){
val = val + capitalFirstLetter(valuearr[i]);
}
//alert(val);
return val;
}
function capitalFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function loaddetails(){
// getting projects details from service
$.ajax({
type: "GET",
async:false,
dataType: "json",
url: "http://localhost:8081/GetHelpServices/getProjects",
success: function(data) {
console.log("projects ajax"+JSON.stringify(data));
for(var j=0; j< data.length; j++){
projects.push(data[j]);
projectoptions = projectoptions + "<option>"+data[j].projectName+"</option>";
}
document.getElementById('projects').innerHTML = projectoptions;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(' Error in processing! '+errorThrown);
}
});
// getting modules details from service
$.ajax({
type: "GET",
async:false,
dataType: "json",
url: "http://localhost:8081/GetHelpServices/getModules",
success: function(data) {
console.log("modules ajax"+data.length);
for(var j=0; j< data.length; j++){
modules.push(data[j]);
moduleoptions = moduleoptions + "<option>"+data[j].moduleName+"</option>";
}
document.getElementById('modules').innerHTML = moduleoptions;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(' Error in processing! '+errorThrown);
}
});
entity = ["Employee","Student"];
for(var j=0; j< entity.length; j++){
entitiyoptions = entitiyoptions + "<option>"+entity[j]+"</option>";
}
document.getElementById('entities').innerHTML = entitiyoptions;
/* datapropertyoptions =
"<option >text</option>" +
"<option >number</option>" +
"<option >boolean</option>" +
"<option >date</option>" + entitiyoptions + "";
document.getElementById('dataproperties').innerHTML = datapropertyoptions; */
}
$(document).ready(function(){
$("#generateArtifacts").click(function(){
var cellbl;
var celdpt;
var infocelarr=[];
var infoproject=document.getElementById("mainproject").value;
var infomodule=document.getElementById("mainmodule").value;
var infoentity=document.getElementById("mainentity").value;
for(var k=0; k<modules.length; k++){
console.log("modules "+modules.length);
console.log("modules "+modules[k].moduleName);
console.log("modules "+infomodule);
if(modules[k].moduleName.trim() == infomodule.trim()){
alert(modules[k].moduleId);
alert(infomodule);
moduleid = modules[k].moduleId;
}
}
for(var k=0; k<projects.length; k++){
console.log("projects "+projects.length);
console.log("projects name "+projects[k].projectName);
console.log("projects read name"+infoproject);
if(projects[k].projectName.trim() === infoproject.trim()){
alert(projects[k].projectId);
alert(infoproject);
projectid = projects[k].projectId;
}
}
infoproject = upperCamelCase(infoproject.toLowerCase());
infomodule = lowercase(infomodule.toLowerCase());
infoentity = upperCamelCase(infoentity.toLowerCase());
var dbinfo = {"primaryKey":"Id"};
console.log(projects);
var infopanelobj = {'"projectId"': ""+projectid+"", '"projectName"':infoproject, '"moduleId"': ""+moduleid+"", '"moduleName"':infomodule, '"entityName"':infoentity,'"fields"':myarr,'"dbinfo"':dbinfo};
infopanelarr.push(infopanelobj);
//finalarr.push({infopanel:infopanelarr});
console.log(infopanelarr);
// Posting the data
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "POST",
async:false,
dataType: "json",
data : JSON.stringify(infopanelobj),
url: "http://localhost:8081/GetHelpServices/insertArtifact",
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(' Error in processing! '+jqXHR);
console.log(' Error in processing! '+textStatus);
console.log(' Error in processing! '+errorThrown);
}
});
});
});
$(document).ready(function(){
var new_dialog = function (type, row) {
var dlg = $("#dialog-form").clone();
var fieldname = dlg.find(("#fieldname")),
fieldtype = dlg.find(("#fieldtype")),
fieldtobeassociated = dlg.find(("#fieldtobeassociated")),
association = dlg.find(("#association")),
Mandatory = dlg.find(("#Mandatory")),
Unique = dlg.find(("#Unique"));
type = type || 'Create';
var config = {
autoOpen: true,
height: 600,
width: 500,
modal: true,
buttons: {
"Create an account": save_data,
"Cancel": function () {
dlg.dialog("close");
}
},
close: function () {
dlg.remove();
}
};
if (type === 'Edit') {
config.title = "Edit User";
// _.remove(myarr, {"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text()});
console.log(myarr);
get_data();
delete (config.buttons['Create an account']);
config.buttons['Edit account'] = function () {
row.remove();
save_data();
};
}
dlg.dialog(config);
function get_data() {
var _fieldname = $(row.children().get(0)).text();
// _password = $(row.children().get(2)).text();
fieldname.val(_fieldname);
// password.val(_password);
}
function save_data() {
var datatype=fieldtype.find("option:selected").text();
if (datatype == "number" || datatype == "text" || datatype == "date" || datatype == "boolean"){
var ob ={"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text()};
}
else {
var ob ={"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text(),
"fieldToBeDisplayedInDropDown":fieldtobeassociated.find("option:selected").text(),
"associationType":association.find("option:selected").text()
};
}
var temp ={"fieldId":fieldname.val()};
var index = _.findIndex(myarr, {"fieldId":fieldname.val()});
console.log(type);
if (index > -1){
myarr.splice(index, 1, ob);
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
dlg.dialog("close");
}
else{
myarr.push(ob);
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
dlg.dialog("close");
}
console.log(myarr);
}
};
$(document).on('click', 'span.delete', function () {
$(this).closest('tr').find('td').fadeOut(200,
function () {
// alert($(this).text());
$(this).parents('tr:first').remove();
});
return false;
});
$(document).on('click', 'td a.edit', function () {
new_dialog('Edit', $(this).parents('tr'));
return false;
});
$("#create-user").button().click(new_dialog);
});
</script>
<body onload="loaddetails()">
<div class="container" >
<h2>UI Details</h2>
<form>
<div class="form-group">
<div class="row">
<div class="col-md-4">
<label for="inputdefault">Project</label>
<input class="form-control" list="projects" id="mainproject" name="project">
<datalist id="projects">
</datalist>
</div>
<div class="col-md-4">
<label for="inputdefault">Module</label>
<input class="form-control" list="modules" id="mainmodule" name="module">
<datalist id="modules">
</datalist>
</div>
<div class="col-md-4">
<label for="inputlg">Entity</label>
<input class="form-control" list="entities" id="mainentity" name="module">
<datalist id="entities">
</datalist>
</div>
</div>
</div>
</form>
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">
All form fields are required.</p>
<form>
<fieldset>
<label for="fieldname">
Field Name*</label>
<input class="form-control " type="text" name="fieldname" id="fieldname" value="" class="text ui-widget-content ui-corner-all" />
<br>
<label for="fieldtype">
Type*</label>
<select class="form-control " id="fieldtype" >
<option value="1">text</option>
<option value="2">boolean</option>
<option value="3">number</option>
<option value="4">date</option>
<option value="4">Student</option>
</select>
<br>
<label for="fieldtobeassociated">
Field to be associated</label>
<select class="form-control " id="fieldtobeassociated" >
<option value="1">name</option>
<option value="2">address</option>
</select>
<br>
<label for="association">
Association Type</label>
<select class="form-control " id="association" >
<option value="1">Foreign Key</option>
<option value="2">One-to-One</option>
<option value="2">One-to-Many</option>
<option value="2">Many-to-One</option>
<option value="2">Many-to-Many</option>
<option value="2">Many-to-Many+Joint Tables</option>
</select>
<br>
<div class="checkbox">
<label><input type="checkbox" value="Mandatory" id="Mandatory">Mandatory</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="Unique" id="Unique">Unique</label>
</div>
</fieldset>
</form>
</div>
<div class="container" >
<div id="users-contain" class="ui-widget">
<h2>Fields</h2>
<button id="create-user">
Add Fields</button>
<table id="users" class="ui-widget ui-widget-content">
<thead>
<tr class="ui-widget-header ">
<th>Field Name </th>
<th>Type</th>
<th> Update</th>
<th> Remove</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
<a class="btn btn-success " id="generateArtifacts">Generate Artifacts</a> <a class="btn btn-danger " onclick="resetpage()">Reset Artifacts</a>
</div>
</body>
</html>
In the above code, I want to hide/show div on jQuery dialog on click onchange event on the same dialog's select option element.
Based on your example, you will want to ensure you are only loading jQuery 3.2.1 and not both.
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js" type="text/javascript"></script>
I have just refined my answer and posting below. the below code working properly with my expected requirement. But need some suggestion on reading table outerHTML data.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script
src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<style type="text/css">
</style>
</head>
<script type="text/javascript">
var myarr = [];
var finalarr = [];
var infopanelarr = [];
var datagridarray = [];
var switchflag = 0;
var datapropertyoptions = "";
var entitiyoptions = "";
var projectoptions = "";
var moduleoptions = "";
var datapropertyoptions = "";
var projects = [];
var modules = [];
var entity = [];
var projectid = 0;
var moduleid = 0;
var flag=true;
function resetpage() {
location.reload();
loaddetails();
}
function lowercase(value) {
var value = value.replace(/\s+/g, '');
return value.toLowerCase();
}
function upperCamelCase(value) {
var valuearr = value.split(" ");
var val = "";
for (var i = 0; i < valuearr.length; i++) {
val = val + capitalFirstLetter(valuearr[i]);
}
return val;
}
function lowerCamelCase(value) {
var valuearr = value.split(" ");
var val = valuearr[0].toLowerCase();
for (var i = 1; i < valuearr.length; i++) {
val = val + capitalFirstLetter(valuearr[i]);
}
//alert(val);
return val;
}
function capitalFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function loaddetails(){
}
function isPrimitive(datatype){
if (datatype == "text" || datatype == "number" || datatype == "date" || datatype == "boolean"){
flag = true;
}
else {
flag=false;
}
return flag;
}
function onFieldTypeChange(){
var entityoptions = "";
var element = document.getElementById("fieldtype").value;
if (isPrimitive(element)){
//alert('hi');
entityoptions = "<option>id</option><option>name</option><option>address</option>";
$('#entityProperties').hide();
}
else {
entityoptions = "<option value='111'>Student</option><option value='112'>Employee</option><option value='113'>Address</option>";
$('#entityProperties').show();
}
document.getElementById("fieldtobeassociated").innerHTML = entityoptions;
}
function insert_save_row(){
var fieldname=document.getElementById("fieldname").value;
var fieldtype=document.getElementById("fieldtype").value;
var table=document.getElementById("fields");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr class='item' id='row"+table_len+"'><td class='theCell' id='fieldname"+table_len+"'>"+fieldname+"</td><td class='theCell' id='fieldtype"+table_len+"'>"+fieldtype+"</td><td><input type='button' class='btn btn-success' id='edit_button"+table_len+"' value='Edit' class='edit' onclick='edit_row("+table_len+")'></td><td> <input type='button' class='btn btn-danger' value='Delete' class='delete' onclick='delete_row("+table_len+")'></td></tr>";
document.getElementById("save").style.display="block";
document.getElementById("edit").style.display="none";
//alert(fieldtype);
if (isPrimitive(fieldtype))
$('#entityProperties').hide();
else
$('#entityProperties').show();
$('#myModal').modal('hide');
}
function edit_row(no)
{
var name=document.getElementById("fieldname"+no);
var type=document.getElementById("fieldtype"+no);
var vname = name.innerHTML;
var vtype = type.innerHTML;
document.getElementById("temp_row_no").value = no;
document.getElementById("fieldname").value = vname;
document.getElementById("fieldtype").value = vtype;
document.getElementById("save").style.display="none";
document.getElementById("edit").style.display="block";
if (isPrimitive(vtype.trim()))
$('#entityProperties').hide();
else
$('#entityProperties').show();
$('#myModal').modal('show');
}
function delete_row(no)
{
document.getElementById("row"+no+"").outerHTML="";
}
function edit_save_row()
{
var no = document.getElementById("temp_row_no").value;
var name=document.getElementById("fieldname").value;
var type=document.getElementById("fieldtype").value;
document.getElementById("fieldname"+no).innerHTML=name;
document.getElementById("fieldtype"+no).innerHTML=type;
if (isPrimitive(type))
$('#entityProperties').hide();
else
$('#entityProperties').show();
$('#myModal').modal('hide');
}
function addField(){
document.getElementById("save").style.display="block";
document.getElementById("edit").style.display="none";
document.getElementById("fieldname").value = "";
document.getElementById("fieldtype").value ="";
$('#entityProperties').hide();
$('#myModal').modal('show');
}
$(document).ready(function(){
var cellbl, celdpt, infocelarr=[];
$("#generateArtifacts").click(function(){
var x = document.getElementById("fields").rows.length;
alert(document.getElementById("fields").tBodies.item(0).innerHTML);
var table = document.getElementById("fields");
for (var i = 3, cell; cell = table.cells[i]; i++) {
alert(i+"--"+cell);
}
var projectid = document.getElementById("mainproject").value
var infoproject=document.getElementById("mainproject").text;
var infomodule=document.getElementById("mainmodule").value;
var infoentity=document.getElementById("mainentity").value;
/* infoproject = upperCamelCase(infoproject.toLowerCase());
infomodule = lowercase(infomodule.toLowerCase());
infoentity = upperCamelCase(infoentity.toLowerCase()); */
var dbinfo = {"primaryKey":"Id"};
var infopanelobj = {'"projectId"': ""+projectid+"", '"projectName"':infoproject, '"moduleId"': ""+moduleid+"", '"moduleName"':infomodule, '"entityName"':infoentity,'"fields"':infocelarr,'"dbinfo"':dbinfo};
console.log(infopanelobj);
});
});
</script>
<body >
<div class="container">
<h2>UI Details</h2>
<form>
<div class="form-group">
<div class="row">
<div class="col-md-4">
<label for="inputdefault">Project</label>
<input class="form-control" list="projects" id="mainproject" name="project">
<datalist id="projects"> <option value="Chrome"></option></datalist>
</div>
<div class="col-md-4">
<label for="inputdefault">Module</label>
<input class="form-control" list="modules" id="mainmodule" name="module">
<datalist id="modules"><option value="Chrome"></option></datalist>
</div>
<div class="col-md-4">
<label for="inputlg">Entity</label> <input class="form-control"
list="entities" id="mainentity" name="module">
<datalist id="entities"><option value="Chrome"></option> </datalist>
</div>
</div>
</div>
</form>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h4 class="modal-title">Field Details</h4>
</div>
<div class="modal-body">
<label for="fieldname"> Field Name*</label> <input
class="form-control " type="text" name="fieldname" id="fieldname"
value="" class="text ui-widget-content ui-corner-all" /> <br>
<label for="fieldtype2"> Type*</label>
<input class="form-control" list="fieldtypelist" id="fieldtype" onchange="onFieldTypeChange()">
<datalist id="fieldtypelist"><option >text</option><option >number</option><option >date</option></datalist>
<div id="entityProperties">
<br/><label for="fieldtobeassociated"> Field to be
associated</label> <select class="form-control " id="fieldtobeassociated">
</select> <br> <label for="association"> Association Type</label> <select
class="form-control " id="association">
<option value="1">Foreign Key</option>
<option value="2">One-to-One</option>
<option value="2">One-to-Many</option>
<option value="2">Many-to-One</option>
<option value="2">Many-to-Many</option>
<option value="2">Many-to-Many+Joint Tables</option>
</select> <br>
<div class="checkbox">
<label><input type="checkbox" value="Mandatory"
id="Mandatory">Mandatory</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="Unique" id="Unique">Unique</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" id="save" class="btn btn-primary pull-right" onclick="insert_save_row()">Save</button>
<button type="button" id="edit" class="btn btn-primary pull-right" onclick="edit_save_row()" style="display:none">Save</button>
</div>
</div>
</div>
</div>
<div class="container">
<h2>Fields</h2>
<a href="#myModal" class="btn btn-lg btn-primary" onclick="addField()">Launch
Demo Modal</a>
<br/><br/><br/>
<table id="fields" class="table table-striped"">
<thead class="thead-default">
<tr >
<th>Field Name</th>
<th>Type</th>
<th>Update</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<tr id="rows">
</tr>
</tbody>
</table>
<br/><br/><br/>
<a class="btn btn-lg btn-primary" " id="generateArtifacts">Generate
Artifacts</a> <a class="btn btn-lg btn-primary" onclick="resetpage()">Reset
Artifacts</a>
<input id="temp_row_no" style="display:none"></input>
</div>
</body>
</html>
I am adding data to table outerHMTL in javascript. How to read its table contents. Please suggest.
I have modified my code in different way. Initially my problem is that i am unable to populate data for second dropdown onchange event of first dropdown on same jquery ui dialog. I have used jquery ui dialog's clone() method. somehow it did't work. But After cleaning up code and adding different versions of jquery, able to generate another dialog on top of existing dialog box and able to set the data properly.
var nestedfiled="";
var nestedassociation="";
var flag=true;
$(document).ready(function(){
$( "#dialog-form1" ).dialog({
autoOpen: false,
modal: true,
buttons: {
"Submit": function(){
var ftb = $( "#dialog-form1");
var kk= ftb.find("#fieldtobeassociated");
var bb= ftb.find("#association");
nestedfiled = kk.find("option:selected").text();
nestedassociation = bb.find("option:selected").text();
flag=false;
$(this).dialog("close");
},
Cancel: function() {
$(this).dialog('close');
}
}
});
var new_dialog = function (type, row) {
var dlg = $("#dialog-form").clone();
nestedfiled = "" ;
nestedassociation = "";
var fieldname = dlg.find(("#fieldname")),
fieldtype = dlg.find(("#fieldtype")),
fieldtobeassociated = dlg.find(("#fieldtobeassociated")),
association = dlg.find(("#association")),
Mandatory = dlg.find(("#Mandatory")),
Unique = dlg.find(("#Unique"));
type = type || 'Create';
var config = {
autoOpen: true,
height: 600,
width: 500,
modal: true,
buttons: {
"Create an account": save_data,
"Cancel": function () {
dlg.dialog("close");
}
},
close: function () {
dlg.remove();
}
};
if (type === 'Edit') {
config.title = "Edit User";
// _.remove(myarr, {"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text()});
console.log(myarr);
get_data();
delete (config.buttons['Create an account']);
config.buttons['Edit account'] = function () {
row.remove();
save_data();
};
}
dlg.dialog(config);
function get_data() {
var _fieldname = $(row.children().get(0)).text();
// _password = $(row.children().get(2)).text();
fieldname.val(_fieldname);
// password.val(_password);
}
function save_data() {
var datatype=fieldtype.find("option:selected").text();
if (datatype == "number" || datatype == "text" || datatype == "date" || datatype == "boolean") {
var ob ={"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text()};
var temp ={"fieldId":fieldname.val()};
var index = _.findIndex(myarr, {"fieldId":fieldname.val()});
console.log(type);
if (index > -1){
myarr.splice(index, 1, ob);
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
dlg.dialog("close");
}
else{
myarr.push(ob);
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
dlg.dialog("close");
}
}
else {
flag=true;
$( "#dialog-form1").find(("#fieldtobeassociated")).empty();
$( "#dialog-form1").find(("#fieldtobeassociated")).append("<option>12</option><option>13</option>");
/* .data('param_1', 'whateverdata') */
if(nestedfiled == "" && nestedassociation == "")
$( "#dialog-form1").dialog("open");
var ob ={"fieldId":fieldname.val(),"type":fieldtype.find("option:selected").text(),
"fieldToBeDisplayedInDropDown":nestedfiled,
"associationType":nestedassociation
};
var index = _.findIndex(myarr, {"fieldId":fieldname.val()});
console.log(type);
if (index > -1){
myarr.splice(index, 1, ob);
if(nestedfiled !== "" && nestedassociation !== "")
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
dlg.dialog("close");
}
else{
myarr.push(ob);
if(nestedfiled !== "" && nestedassociation !== "")
$("#users tbody").append("<tr>" + "<td>" + fieldname.val() + "</td>" + "<td>" + (fieldtype.find("option:selected").text() + ' ') + "</td>" + "<td><a href='' class='edit'>Edit</a></td>" + "<td><span class='delete'><a href=''>Delete</a></span></td>" + "</tr>");
//dlg.dialog("close");
}
}
console.log(myarr);
}
};
$(document).on('click', 'span.delete', function () {
$(this).closest('tr').find('td').fadeOut(200,
function () {
// alert($(this).text());
$(this).parents('tr:first').remove();
});
return false;
});
$(document).on('click', 'td a.edit', function () {
new_dialog('Edit', $(this).parents('tr'));
return false;
});
$("#create-user").button().click(new_dialog);
});
</script>
<body onload="loaddetails()">
<div class="container" >
<h2>UI Details</h2>
<form>
<div class="form-group">
<div class="row">
<div class="col-md-4">
<label for="inputdefault">Project</label>
<input class="form-control" list="projects" id="mainproject" name="project">
<datalist id="projects">
</datalist>
</div>
<div class="col-md-4">
<label for="inputdefault">Module</label>
<input class="form-control" list="modules" id="mainmodule" name="module">
<datalist id="modules">
</datalist>
</div>
<div class="col-md-4">
<label for="inputlg">Entity</label>
<input class="form-control" list="entities" id="mainentity" name="module">
<datalist id="entities">
</datalist>
</div>
</div>
</div>
</form>
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">
All form fields are required.</p>
<form>
<fieldset>
<label for="fieldname">
Field Name*</label>
<input class="form-control " type="text" name="fieldname" id="fieldname" value="" class="text ui-widget-content ui-corner-all" />
<br>
<label for="fieldtype2">
Type*</label>
<select class="form-control " id="fieldtype" >
<option value="1">text</option>
<option value="2">boolean</option>
<option value="3">number</option>
<option value="4">date</option>
<option value="4">Student</option>
<option value="4">Employee</option>
</select>
</fieldset>
</form>
</div>
<div id="dialog-form1" title="Create new user">
<p class="validateTips">
All form fields are required.</p>
<form>
<fieldset>
<br>
<label for="fieldtobeassociated">
Field to be associated</label>
<select class="form-control " id="fieldtobeassociated" >
</select>
<br>
<label for="association">
Association Type</label>
<select class="form-control " id="association" >
<option value="1">Foreign Key</option>
<option value="2">One-to-One</option>
<option value="2">One-to-Many</option>
<option value="2">Many-to-One</option>
<option value="2">Many-to-Many</option>
<option value="2">Many-to-Many+Joint Tables</option>
</select>
<br>
<div class="checkbox">
<label><input type="checkbox" value="Mandatory" id="Mandatory">Mandatory</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="Unique" id="Unique">Unique</label>
</div>
</fieldset>
</form>
</div>
<div class="container" >
<div id="users-contain" class="ui-widget">
<h2>Fields</h2>
<button id="create-user">
Add Fields</button>
<table id="users" class="ui-widget ui-widget-content">
<thead>
<tr class="ui-widget-header ">
<th>Field Name </th>
<th>Type</th>
<th> Update</th>
<th> Remove</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
<a class="btn btn-success " id="generateArtifacts">Generate Artifacts</a> <a class="btn btn-danger " onclick="resetpage()">Reset Artifacts</a>
</div>
</body>
</html>
Thank you for suggestions.
I have made an example of add/remove data in basic table in React JS. Everything is working, but now i m stuck to get row value into textboxes for edit operation.
Tried to get variable value like var cname = this.refs.cname.getDOMNode().value; from one component NewRow function handleRowSubmit and set its value in another component Company function handleRowEdit.But nothing works for me.
JSX file :
var CompanyApp = React.createClass({
getInitialState: function() {
return {
companylist : this.props.companies
};
},
handleNewRowSubmit: function(newcompany) {
this.setState( {companylist: this.state.companylist.concat([newcompany])} );
},
handleCompanyRemove: function( company ) {
var index = -1;
var clength = this.state.companylist.length;
for( var i = 0; i < clength; i++ ) {
if( this.state.companylist[i].cname === company.cname ) {
index = i;
break;
}
}
this.state.companylist.splice( index, 1 );
this.setState( {companylist: this.state.companylist} );
},
render: function() {
var tableStyle = {width: '100%'};
var leftTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
var rightTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
return (
<table style={tableStyle}>
<tr>
<td style={leftTdStyle}>
<CompanyList clist={this.state.companylist} onCompanyRemove={this.handleCompanyRemove}/>
</td>
<td style={rightTdStyle}>
<NewRow onRowSubmit={this.handleNewRowSubmit}/>
</td>
</tr>
</table>
);
}
});
var CompanyList = React.createClass({
handleCompanyRemove: function(company){
this.props.onCompanyRemove(company);
},
render: function() {
var companies = [];
var that = this;
// TODO: Needs to find out why that = this made it work; Was getting error that onCompanyDelete is not undefined
this.props.clist.forEach(function(company) {
companies.push(<Company company={company} onCompanyDelete={that.handleCompanyRemove} /> );
});
return (
<div>
<h3>List of Companies</h3>
<table className="table table-striped" id="tableId">
<thead><tr><th>Company Name</th><th>Employees</th><th>Head Office</th><th>Action</th></tr></thead>
<tbody>{companies}</tbody>
</table>
</div>
);
}
});
var Company = React.createClass({
handleRemoveCompany: function() {
this.props.onCompanyDelete( this.props.company );
return false;
},
handleRowEdit:function() {
var name = this.state.vals;
var rows = document.getElementsByTagName('tr');
var HO = '' ;
var CompName = '' ;
var noOfEmployees = '' ;
for ( var i = 1; i < rows.length; i++)
{
rows[i].i = i;
rows[i].onclick = function()
{
CompName = rows[this.i].cells[0].innerHTML;
noOfEmployees = rows[this.i].cells[1].innerHTML;
HO = rows[this.i].cells[2].innerHTML;
alert("rows---" + CompName + noOfEmployees + JSON.stringify(vals));
// here i got the selected row but don't know how to get textbox control here
};
}
},
render: function() {
return (
<tr>
<td>{this.props.company.cname}</td>
<td>{this.props.company.ecount}</td>
<td>{this.props.company.hoffice}</td>
<td><input type="button" className="btn btn-primary" value="Edit" onClick = {this.handleRowEdit} /></td>
<td><input type="button" className="btn btn-primary" value="Remove" onClick = {this.handleRemoveCompany}/></td>
</tr>
);
}
});
var NewRow = React.createClass({
handleSubmit: function(cname) {
var cname = this.refs.cname.getDOMNode().value;
var ecount = this.refs.ecount.getDOMNode().value;
var hoffice = this.refs.hoffice.getDOMNode().value;
var newrow = {cname: cname, ecount: ecount, hoffice: hoffice };
this.props.onRowSubmit(newrow);
this.refs.cname.getDOMNode().value = '';
this.refs.ecount.getDOMNode().value = '';
this.refs.hoffice.getDOMNode().value = '';
return false;
},
componentDidMount: function(){
this.refs.cname.getDOMNode().focus();
},
render: function() {
var inputStyle = {padding:'12px'}
return (
<div className="well">
<h3>Add A Company</h3>
<form onSubmit={this.handleSubmit}>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Company Name" ref="cname" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Employee Count" ref="ecount" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Headoffice" ref="hoffice" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="submit" className="btn btn-primary" value="Add Company" required/>
</div>
</form>
</div>
);
}
});
var defCompanies = [{cname:"Infosys Technologies",ecount:150000,hoffice:"Bangalore"},
{cname:"TCS",ecount:140000,hoffice:"Mumbai"}];
React.render( <CompanyApp companies={defCompanies} />, document.getElementById("companyApp"));
You need to pass the selected company into your new row component.
To do this create a new function, and pass the information back up your component chain, then pass it into the new row component.
handleRowEdit:function() {
var HO = this.props.company.cname;
var CompName = this.props.company.hoffice;
var noOfEmployees = this.props.company.ecount;
console.log("rows---" + CompName + noOfEmployees);
this.props.onEdit(this.props.company)
}
The below plnkr gets the information where it needs to go. I will leave you to pulling out the company info and adding them into the correct fields.
http://embed.plnkr.co/ve24aHo9MbkyhxIzaE4Z/
I have found answer for my own question!!
Just create textbox inside Row for Edit operation.
JSX file :
var CompanyApp = React.createClass({
getInitialState: function() {
return {
companylist : this.props.companies
};
},
handleNewRowSubmit: function(newcompany) {
this.setState( {companylist: this.state.companylist.concat([newcompany])} );
},
handleCompanyRemove: function( company ) {
var index = -1;
var clength = this.state.companylist.length;
for( var i = 0; i < clength; i++ ) {
if( this.state.companylist[i].cname === company.cname ) {
index = i;
break;
}
}
this.state.companylist.splice( index, 1 );
this.setState( {companylist: this.state.companylist} );
},
render: function() {
var tableStyle = {width: '100%'};
var leftTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
var rightTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
return (
<table style={tableStyle}>
<tr>
<td style={leftTdStyle}>
<CompanyList clist={this.state.companylist} onCompanyRemove={this.handleCompanyRemove} />
</td>
<td style={rightTdStyle}>
<NewRow onRowSubmit={this.handleNewRowSubmit } />
</td>
</tr>
</table>
);
}
});
var CompanyList = React.createClass({
handleCompanyRemove: function(company){
this.props.onCompanyRemove(company);
},
render: function() {
var companies = [];
var that = this;
// TODO: Needs to find out why that = this made it work; Was getting error that onCompanyDelete is not undefined
this.props.clist.forEach(function(company) {
companies.push(<Company company={company} onCompanyDelete={that.handleCompanyRemove} /> );
});
return (
<div>
<h3>List of Companies</h3>
<table className="table table-striped" id="tableId">
<thead><tr><th>Company Name</th><th>No. Of Employees</th><th>Head Office</th><th>Action</th></tr></thead>
<tbody>{companies}</tbody>
</table>
</div>
);
}
});
var Company = React.createClass({
getInitialState : function(){
return {
editing : false,
cname : this.props.company.cname,
ecount : this.props.company.ecount,
hoffice : this.props.company.hoffice,
};
},
_onchangeCname:function(event) {
this.setState({cname : event.target.value});
},
_onchangeEmpCount:function(event){
this.setState({ecount : event.target.value});
},
_onchangeCompHO:function(event){
this.setState({hoffice : event.target.value});
},
handleRemoveCompany: function() {
this.props.onCompanyDelete( this.props.company );
return false;
},
handleRowEdit:function() {
var getCName = this.state.cname.trim();
var getEmpCount = this.state.ecount;
var getCompHO = this.state.hoffice;
this.setState({
getCName : this.state.cname,
getEmpCount : this.state.ecount,
getCompHO : this.state.hoffice
})
this.setState({editing : true });
return false;
},
handleUpdateRow:function(){
var getCName = this.state.cname.trim();
var getEmpCount = this.state.ecount;
var getCompHO = this.state.hoffice;
this.setState({
getCName : this.state.cname,
getEmpCount : this.state.ecount,
getCompHO : this.state.hoffice
})
alert("updated vals "+ getCName+","+getEmpCount+","+getCompHO );
this.props.company.cname = getCName;
this.props.company.ecount = getEmpCount;
this.props.company.hoffice = getCompHO;
this.setState({editing : false });
return false;
},
handleCancelEdit : function(){
this.setState({editing : false });
return false;
},
render: function() {
var inputStyle = {padding:'-3px'};
var EditBtn = <input type ="button" className ="btn btn-primary"
value ="Edit" onClick ={this.handleRowEdit} />;
var UpdateBtn = <input type ="button" className ="btn btn-primary"
value ="Update" onClick ={this.handleUpdateRow} />;
var RemoveBtn = <input type ="button" className ="btn btn-primary"
value ="Remove" onClick ={this.handleRemoveCompany}/>;
var CancelEditBtn = <input type ="button" className ="btn btn-primary"
value ="Cancel" onClick = {this.handleCancelEdit}/>;
return(
<tr>
<td>{this.state.editing ? <input type="text" style={inputStyle} ref="CompName"
value={this.state.cname} onChange={this._onchangeCname} />
: this.props.company.cname}</td>
<td>{this.state.editing ? <input type="text" style={inputStyle} ref="EmpCount"
value={this.state.ecount} onChange={this._onchangeEmpCount} />
: this.props.company.ecount}</td>
<td>{this.state.editing ? <input type="text" style={inputStyle} ref="CompHO"
value={this.state.hoffice} onChange={this._onchangeCompHO}/>
: this.props.company.hoffice}</td>
<td>{this.state.editing ? UpdateBtn : EditBtn }</td>
<td>{this.state.editing ? CancelEditBtn : RemoveBtn}</td>
</tr>
)
}
});
var NewRow = React.createClass({
handleSubmit: function() {
var cname = this.refs.cname.getDOMNode().value;
var ecount = this.refs.ecount.getDOMNode().value;
var hoffice = this.refs.hoffice.getDOMNode().value;
var newrow = {cname: cname, ecount: ecount, hoffice: hoffice };
this.props.onRowSubmit(newrow);
this.refs.cname.getDOMNode().value = '';
this.refs.ecount.getDOMNode().value = '';
this.refs.hoffice.getDOMNode().value = '';
return false;
},
componentDidMount: function(){
this.refs.cname.getDOMNode().focus();
},
render: function() {
var inputStyle = {padding:'12px'}
return (
<div className="well">
<h3>Add A Company</h3>
<form onSubmit={this.handleSubmit} >
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Company Name"
name="cname" ref="cname" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Employee Count"
ref="ecount" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="text" className="form-control col-md-8" placeholder="Headoffice"
ref="hoffice" required/>
</div>
<div className="input-group input-group-lg" style={inputStyle}>
<input type="submit" className="btn btn-primary" value="Add Company" />
</div>
</form>
</div>
);
}
});
var defCompanies = [{cname:"Infosys Technologies",ecount:150000,hoffice:"Bangalore"},
{cname:"TCS",ecount:140000,hoffice:"Mumbai"}];
React.render(<CompanyApp companies={defCompanies} />, document.getElementById("companyApp"));
Now its working all operations :)
http://embed.plnkr.co/N25QauVLvbABmSDIBU9o/
I'm using MVC Http.BeginForm to create a search form.
Now I want to add create button, which opens Popup, but when I press it HttpPost event in controller fires up. How can I prevent HttpPost event to fire up when popup is pressed?
#using (Html.BeginForm())
{
<table border="0">
<tr>
<td style="padding: 5px;">A:</td>
<td style="padding: 5px;">#Html.TextBox("slicplate", "", new { style="width:120px; height:25px;" })</td>
<td style="padding: 5px;">B:</td>
<td style="padding: 5px;">#Html.TextBox("smodelis", "", new { style="width:120px; height:25px;" })</td>
<td style="padding: 5px;">C:</td>
<td style="padding: 5px;">#Html.TextBox("suzsakovas", "", new { style = "width:120px; height:25px;" })</td>
<td style="padding: 5px;">D:</td>
<td style="padding: 5px;">#Html.TextBox("svairuotojas", "", new { style = "width:120px; height:25px;" })</td>
<td style="padding: 5px;" rowspan="3" valign="top"><input type="submit" value="Search" style="height:59px;" /></td>
<td style="padding: 5px;" rowspan="3">
<button class="btn btn-primary" style="height:50px; width:100px;" ng-click="open('new_tp')">Popup button</button>
</td>
</tr>
</table>
}
Open function:
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size, id) {
var modalInstance
if (size == "new_tp") {
modalInstance = $modal.open({
templateUrl: '/Transport/Create',
controller: ModalInstanceCtrl,
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
}
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
And ModalDemoCtrl function:
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$('.modal-dialog').close;
$modalInstance.close($scope.selected.item);
};
$scope.delete = function (id) {
$('.modal-dialog').close;
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Change code from
<button class="btn btn-primary" style="height:50px; width:100px;" ng-click="open('new_tp')">Popup button</button>
To:
<button class="btn btn-primary" type="button" style="height:50px; width:100px;" ng-click="open('new_tp')">Popup button</button>
I can't get this code to page. The table's page size is always the same - the number of items returned from the Web API call. The parameter that is passed-in is ignored (3). Also, the back and forward button elements don't have icons (icon-step-backward and icon-step-forward), but this is secondary to the page size.
HTML
<table class="table">
<thead>
<tr>
<th data-column="LastName">Last Name</th>
<th data-column="FirstName">First Name</th>
<th data-column="EnrollmentDate">Enrollment Date</th>
</tr>
</thead>
<tbody data-bind="foreach: students">
<tr>
<td data-bind="text: LastName" />
<td data-bind="text: FirstName" />
<td data-bind="text: EnrollmentDate" />
</tr>
</tbody>
<tfoot>
<tr>
<td>
Number of items per page:
<select id="pageSizeSelector" data-bind="value: pageSize">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</td>
<td colspan="3">
<button data-bind="click: previousPage" class="btn"><i class="icon-step-backward"></i></button>
Page<label data-bind="text: currentPageIndex() + 1" class="badge"></label>
<button data-bind="click: nextPage" class="btn"><i class="icon-step-forward"></i></button>
</td>
</tr>
</tfoot>
</table>
KNOCKOUT and JQUERY
<script type="text/javascript">
var viewModel = function () {
self = this;
self.currentPage = ko.observable();
self.pageSize = ko.observable(3);
self.currentPageIndex = ko.observable(0);
self.students = ko.observableArray();
self.currentPage = ko.computed(function () {
var pagesize = parseInt(self.pageSize(), 3),
startIndex = pagesize * self.currentPageIndex(),
endIndex = startIndex + pagesize;
return self.students.slice(startIndex, endIndex);
});
self.nextPage = function () {
if (((self.currentPageIndex() + 1) * self.pageSize()) < self.students().length) {
self.currentPageIndex(self.currentPageIndex() + 1);
}
else {
self.currentPageIndex(0);
}
}
self.previousPage = function () {
if (self.currentPageIndex() > 0) {
self.currentPageIndex(self.currentPageIndex() - 1);
}
else {
self.currentPageIndex((Math.ceil(self.students().length / self.pageSize())) - 1);
}
}
}
$(document).ready(function () {
$.ajax({
url: "http://localhost:12769/api/student",
type: "GET"
}).done(function (data) {
var vm = new viewModel();
vm.students(data);
ko.applyBindings(vm);
}).error(function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.responseText || textStatus);
});
});
</script>
JSON Returned From Web API
[{"$id":"1","ID":1,"LastName":"Alexander","FirstMidName":"Carson","EnrollmentDate":"2005-09-01T00:00:00","Enrollments":[{"$id":"2","EnrollmentID":1,"CourseID":1050,"StudentID":1,"Grade":0,"Course":{"$id":"3","CourseID":1050,"Title":"Chemistry","Credits":3},"Student":{"$ref":"1"}},{"$id":"4","EnrollmentID":2,"CourseID":4022,"StudentID":1,"Grade":2,"Course":{"$id":"5","CourseID":4022,"Title":"Microeconomics","Credits":3},"Student":{"$ref":"1"}},{"$id":"6","EnrollmentID":3,"CourseID":4041,"StudentID":1,"Grade":1,"Course":{"$id":"7","CourseID":4041,"Title":"Macroeconomics","Credits":3},"Student":{"$ref":"1"}}]},{"$id":"8","ID":2,"LastName":"Alonso","FirstMidName":"Meredith","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"9","EnrollmentID":4,"CourseID":1045,"StudentID":2,"Grade":1,"Course":{"$id":"10","CourseID":1045,"Title":"Calculus","Credits":4},"Student":{"$ref":"8"}},{"$id":"11","EnrollmentID":5,"CourseID":3141,"StudentID":2,"Grade":4,"Course":{"$id":"12","CourseID":3141,"Title":"Trigonometry","Credits":4},"Student":{"$ref":"8"}},{"$id":"13","EnrollmentID":6,"CourseID":2021,"StudentID":2,"Grade":4,"Course":{"$id":"14","CourseID":2021,"Title":"Composition","Credits":3},"Student":{"$ref":"8"}}]},{"$id":"15","ID":3,"LastName":"Anand","FirstMidName":"Arturo","EnrollmentDate":"2003-09-01T00:00:00","Enrollments":[{"$id":"16","EnrollmentID":7,"CourseID":1050,"StudentID":3,"Grade":null,"Course":{"$ref":"3"},"Student":{"$ref":"15"}}]},{"$id":"17","ID":4,"LastName":"Barzdukas","FirstMidName":"Gytis","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"18","EnrollmentID":8,"CourseID":1050,"StudentID":4,"Grade":null,"Course":{"$ref":"3"},"Student":{"$ref":"17"}},{"$id":"19","EnrollmentID":9,"CourseID":4022,"StudentID":4,"Grade":4,"Course":{"$ref":"5"},"Student":{"$ref":"17"}}]},{"$id":"20","ID":5,"LastName":"Li","FirstMidName":"Yan","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"21","EnrollmentID":10,"CourseID":4041,"StudentID":5,"Grade":2,"Course":{"$ref":"7"},"Student":{"$ref":"20"}}]},{"$id":"22","ID":6,"LastName":"Justice","FirstMidName":"Peggy","EnrollmentDate":"2001-09-01T00:00:00","Enrollments":[{"$id":"23","EnrollmentID":11,"CourseID":1045,"StudentID":6,"Grade":null,"Course":{"$ref":"10"},"Student":{"$ref":"22"}}]},{"$id":"24","ID":7,"LastName":"Norman","FirstMidName":"Laura","EnrollmentDate":"2003-09-01T00:00:00","Enrollments":[{"$id":"25","EnrollmentID":12,"CourseID":3141,"StudentID":7,"Grade":0,"Course":{"$ref":"12"},"Student":{"$ref":"24"}}]},{"$id":"26","ID":8,"LastName":"Olivetto","FirstMidName":"Nino","EnrollmentDate":"2005-09-01T00:00:00","Enrollments":[]}]
One reason it might not be working for you, is that you are using parseInt with a radix of 3. So in your currentPage ko computed, the line var pagesize = parseInt(self.pageSize(), 3) is going to result in a NaN. See the MDN docs for more info.
Here's a helpful paging extension for a KO observable array, and it will clean up your view model as well. See this fiddle for a working example. In your case, your viewmodel would simply be
var viewmodel = function(){
var self = this;
self.students = ko.observableArray().paged(3);
}
Your HTML would be this:
<table data-bind="foreach: students.pagedItems">
<!-- normal data binding syntax here -->
</table>
And some pagination controls. These are using Bootstrap classes, but gives you an idea of how to use them:
<ul class="pagination">
<li data-bind="css: { disabled: students.currentPageIndex() === 0 }">«</li>
</ul>
<ul class="pagination" data-bind="foreach: students.allPages">
<li data-bind="css: { active: pageNumber === ($root.students.currentPageIndex() + 1) }">
</li>
</ul>
<ul class="pagination">
<li data-bind="css: { disabled: students.currentPageIndex() === students.maxPageIndex() }">»</li>
</ul>
<br />
<span data-bind="text: students.currentStatus"></span>
And here's the extension. I have a second option to pass a sorting function in, but it is completely optional.
ko.observableArray.fn.paged = function (perPage, sortComparator) {
var items = this;
items.currentPage = ko.observable();
items.pageSize = ko.observable(perPage);
items.currentPageIndex = ko.observable(0);
items.currentItemPage = ko.computed(function () {
var pagesize = parseInt(items.pageSize(), 10),
startIndex = pagesize * items.currentPageIndex(),
endIndex = startIndex + pagesize;
return this().slice(startIndex, endIndex);
}, items);
items.pagedItems = ko.computed(function () {
var size = parseInt(items.pageSize(), 10),
start = items.currentPageIndex() * size;
if (typeof (sortComparator) === "function") {
var sorted = this().sort(sortComparator);
return sorted.slice(start, start + size);
} else {
return this().slice(start, start + size);
}
}, items);
items.maxPageIndex = ko.computed(function () {
return Math.ceil(this().length / items.pageSize()) - 1;
}, items);
items.allPages = ko.computed(function () {
var pages = [];
for (var i = 0; i <= items.maxPageIndex() ; i++) {
pages.push({ pageNumber: (i + 1) });
}
return pages;
}, items);
items.currentStatus = ko.computed(function () {
var pagesize = parseInt(items.pageSize(), 10),
start = pagesize * items.currentPageIndex(),
end = start + pagesize;
if (items.currentPageIndex() === items.maxPageIndex()) end = this().length;
return 'Showing ' + (start + 1) + ' to ' + end + ' of ' + this().length;
}, items);
items.nextPage = function () {
if (((items.currentPageIndex() + 1) * items.pageSize()) < items().length) {
items.currentPageIndex(items.currentPageIndex() + 1);
} else {
items.currentPageIndex(0);
}
};
items.previousPage = function () {
if (items.currentPageIndex() > 0) {
items.currentPageIndex(items.currentPageIndex() - 1);
} else {
items.currentPageIndex((Math.ceil(items().length / items.pageSize())) - 1);
}
};
items.moveToPage = function (index) {
items.currentPageIndex(index);
};
return items;
};
I am running into problem where i subscribe to propertyChanged event, the subscribed event does fire for entity Modification, but never fires for when setting entity to Deleted.
what might i be doing wrong.
The objective of what i am doing is that, whenever user modifies the row, i want to provide
button at row level to cancel the changes. similarly when user deletes a row, i want to provide a button to unDelete a row. The modification part works as expected, but for Delete it is not working.
I was Expecting that item.entityAspect.setDeleted(), would fire the propertyChanged Event
so that i can update the vlaue of observable IsDeleted,which in turn would update the visibility of the button.
ViewModel
/// <reference path="jquery-1.8.3.js" />
/// <reference path="../linq-vsdoc.js" />
/// <reference path="../linq.min.js" />
/// <reference path="../breeze.intellisense.js" />
/// <reference path="../breeze.debug.js" />
$(document).ready(function () {
//extend country type
var Country = function () {
console.log("Country initialized");
var self = this;
self.Country_ID = ko.observable(0); // default FirstName
self.Country_Code = ko.observable(""); // default LastName
self.Country_Name = ko.observable("");
self.entityState = ko.observable("");
self.hasValidationErrors = ko.observable(false);
self.IsDeleted = ko.observable(false);
self.IsModified = ko.observable(false);
self.templateName = ko.observable("AlwayEditable");
var onChange = function () {
var hasError = self.entityAspect.getValidationErrors().length > 0;
if (hasError)
self.hasValidationErrors(true);
else
self.hasValidationErrors(false);
};
//dummy property to wireup event
//should not be used for any other purpose
self.hasError = ko.computed(
{
read: function () {
self.entityAspect // ... and when errors collection changes
.validationErrorsChanged.subscribe(onChange);
},
// required because entityAspect property will not be available till Query
// return some data
deferEvaluation: true
});
//dummy property to wireupEvent and updated self.entityStateChanged property
self.entityStateChanged = ko.computed({
read: function () {
self.entityAspect.propertyChanged.subscribe(function (changeArgs) {
if (changeArgs.entity.entityAspect.entityState.name == "Deleted") {
self.IsDeleted(false);
}
else if (changeArgs.entity.entityAspect.entityState.name == "Modified")
self.IsModified(true);
}); //subscribe
},
deferEvaluation: true,
// self.entityStateChanged(false)
});
self.fullName = ko.computed(
function () {
return self.Country_Code() + " --- " + self.Country_Name();
});
};
manager.metadataStore.registerEntityTypeCtor("Country", Country);
var countryViewModel = function (manager) {
var self = this;
window.viewModel = self;
self.list = ko.observableArray([]);
self.pageSize = ko.observable(2);
self.pageIndex = ko.observable(0);
self.selectedItem = ko.observable();
self.hasChanges = ko.observable(false);
self.totalRows = ko.observable(0);
self.totalServerRows = ko.observable(0);
self.RowsModified = ko.observable(false);
self.RowsAdded = ko.observable(false);
self.RowsDeleted = ko.observable(false);
self.templateToUse = function (dataItem, context) {
var item = dataItem;
if (!_itemTemplate) {
_itemTemplate = ko.computed(function (item) {
//var x = this;
if (this.entityAspect == "undefined")
return this.templateName("AlwayEditable");
if (this.entityAspect.entityState.name == "Deleted") {
this.templateName("readOnlyTmpl");
return this.templateName();
}
else {
this.templateName("AlwayEditable");
return this.templateName();
}
}, item);
}
if (item.entityAspect.entityState.name == "Deleted") {
item.templateName("readOnlyTmpl");
return item.templateName();
}
else {
item.templateName("AlwayEditable");
return item.templateName();
}
// return _itemTemplate();
}
var _itemTemplate;
self.hasError = ko.computed(
{
read: function () {
self.entityAspect // ... and when errors collection changes
.validationErrorsChanged.subscribe(onChange);
},
// required because entityAspect property will not be available till Query
// return some data
deferEvaluation: true
});
self.acceptChanges = function (item) {
// self.selectedItem().entityAspect.acceptChanges();
self.selectedItem(null);
}
manager.hasChanges.subscribe(function (newvalue) {
self.hasChanges(newvalue.hasChanges);
});
self.edit = function (item, element) {
highlightRow(element.currentTarget, item);
self.selectedItem(item);
};
self.discardChanges = function () {
manager.rejectChanges();
manager.clear();
self.pageIndex(0);
self.loadData();
};
self.cancel = function (item, element) {
item.entityAspect.rejectChanges();
self.selectedItem(null);
};
self.add = function () {
var countryType = manager.metadataStore.getEntityType("Country"); // [1]
var newCountry = countryType.createEntity(); // [2]
//if not using this line, the table is not updated to show this newly added item
self.list.push(newCountry);
manager.addEntity(newCountry); // [3]
self.selectedItem(newCountry);
};
self.remove = function (item) {
item.entityAspect.rejectChanges();
item.entityAspect.setDeleted(); //was expecting that propertychaged subscribe event will fire, but it does not
item.templateName("readOnlyTmpl"); //if i don't do this the template is not changed/updated
item.IsDeleted(true); //have to use this
};
self.UndoDelete = function (item) {
item.entityAspect.rejectChanges();
item.templateName("AlwayEditable");
item.IsDeleted(false);
};
self.save = function () {
if (manager.hasChanges()) {
alertTimerId = setTimeout(function () {
//this works as well
$.blockUI({ message: '<img src="Images/360.gif" /> </p><h1>Please Saving Changes</h1>', css: { width: '275px' } });
}, 700);
manager.saveChanges()
.then(saveSucceeded(alertTimerId))
.fail(saveFailed);
} else {
$.pnotify({
title: 'Save Changes',
text: "Nothing to save"
});
// alert("Nothing to save");
};
};
manager.hasChanges.subscribe(function (newvalue) {
self.hasChanges(newvalue.hasChanges);
});
manager.entityChanged.subscribe(function (changeArg) {
self.RowsDeleted(manager.getEntities(null, [breeze.EntityState.Deleted]).length);
self.RowsModified(manager.getEntities(null, [breeze.EntityState.Modified]).length);
self.RowsAdded(manager.getEntities(null, [breeze.EntityState.Added]).length);
});
//we want maxPageIndex to be recalculated as soon as totalRows or pageSize changes
self.maxPageIndex = ko.dependentObservable(function () {
return Math.ceil(self.totalRows() / self.pageSize()) - 1;
//return Math.ceil(self.list().length / self.pageSize()) - 1;
});
self.previousPage = function () {
if (self.pageIndex() > 1) {
self.pageIndex(self.pageIndex() - 1);
//self.loadData();
getData();
}
};
self.nextPage = function () {
if (self.pageIndex() < self.maxPageIndex()) {
self.pageIndex(self.pageIndex() + 1);
// self.loadData();
getData();
}
};
self.allPages = ko.dependentObservable(function () {
var pages = [];
for (i = 0; i <= self.maxPageIndex() ; i++) {
pages.push({ pageNumber: (i + 1) });
}
return pages;
});
self.moveToPage = function (index) {
self.pageIndex(index);
//self.loadData();
getData();
};
};
// self.loadData
var vm = new countryViewModel(manager);
//ko.validation.group(vm);
ko.applyBindings(vm);
// ko.applyBindingsWithValidation(vm);
vm.loadData();
try {
} catch (e) {
displayModalMessage("Page Error :- Reload the Page", e.message);
}
}); //end document.ready
View
<p><a class="btn btn-primary" data-bind="click: $root.add" href="#" title="Add New Country"><i class="icon-plus"></i> Add Country</a></p>
<span> Search Country Code :</span><input id="txtSearch" type="text" /><input id="BtnSearch" type="button" value="Search" data-bind="click: $root.loadData" />
<!--<table class="table table-striped table-bordered " style="width: 700px">-->
<!--<table id="myTable" class="ui-widget" style="width: 800px">-->
<table id="myTable" class="table table-striped table-bordered " style="width: 1200px">
<caption> <div>
<span class="label label-info">Number of Rows Added </span> <span class="badge badge-info" data-bind="text: RowsAdded"></span> ,
<span class="label label-success">Number of Rows Modified</span> <span class="badge badge-success" data-bind="text: RowsModified"></span> ,
<span class="label label-important">Number of Rows Deleted</span> <span class="badge badge-important" data-bind="text: RowsDeleted"></span>
<p/>
</div></caption>
<thead class="ui-widget-header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Full Name</th>
<th />
</tr>
</thead>
<!--<tbody data-bind=" title:ko.computed(function() { debugger; }), template:{name:templateToUse, foreach: list, afterRender: HighlightRows }" class="ui-widget-content"></tbody>-->
<tbody data-bind=" title:ko.computed(function() { debugger; }), template:{name:templateToUse, foreach: list}" ></tbody>
</table>
<div class="pagination">
<ul><li data-bind="css: { disabled: pageIndex() === 0 }">Previous</li></ul>
<ul data-bind="foreach: allPages">
<li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"></li>
</ul>
<ul><li data-bind="css: { disabled: pageIndex() === maxPageIndex() }">Next</li></ul>
</div>
<!--<input id="Button1" type="button" value="Save" data-bind="attr: { disabled: !hasChanges()}, click:saveChanges" />-->
<a class="btn btn-success btn-primary" data-bind="click: $root.save, css: { disabled: !$root.hasChanges()}" href="#" title="Save Changes"> Save Changes</a>
<!-- <input id="Button3" type="button" value="Create New" data-bind="click:AddNewCountry" />
<input id="Button4" type="button" value="Discard and reload data" data-bind="click:discardreload, attr: { disabled: !hasChanges()}" /> -->
<a class="btn btn-danger btn-primary" data-bind="click: $root.discardChanges, css: { disabled: !$root.hasChanges()}" href="#" title="Discard Changes"><i class="icon-refresh"></i> Discard & Reload</a>
<script id="readOnlyTmpl" type="text/html">
<tr >
<td>
<span class="label " data-bind="text: Country_Code "></span>
<div data-bind="if: hasValidationErrors">
<span class="label label-important" data-bind="text: $data.entityAspect.getValidationErrors('Country_Code')[0].errorMessage ">Important</span>
</div>
</td>
<td>
<span class="label " data-bind="text: Country_Name "></span>
<p data-bind="validationMessage: Country_Name"></p>
<span data-bind='visible: ko.computed(function() { debugger; }), text: Country_Name.validationMessage'> </span>
</td>
<td> <span class="label " data-bind="text: fullName "></span>
</td>
<td >
<a class="btn btn-danger" data-bind="click: $root.cancel, visible: $data.IsModified" href="#" title="cancel/undo changes">Undo Changes<i class="icon-trash"></i></a>
<a class="btn btn-danger" data-bind="click: $root.remove, visible: !$data.IsDeleted() " href="#" title="Delete this Row">Delete<i class="icon-remove"></i></a>
<a class="btn btn-danger" data-bind="click: $root.UndoDelete, visible: $data.IsDeleted() " href="#" title="Undo Delete">Un Delete<i class="icon-remove"></i></a>
</td>
</tr>
</script>
<script id="AlwayEditable" type="text/html">
<tr >
<td><input type="text" placeholder="Country Code" data-bind="value: Country_Code , uniqueName: true, css: { error: hasValidationErrors }, valueUpdate: 'afterkeydown'"/>
<!-- <div data-bind="if: $data.entityAspect.getValidationErrors().length>0">
<pre data-bind="text: $data.entityAspect.getValidationErrors('Country_Code')[0].errorMessage "></pre>
</div>-->
<div data-bind="if: hasValidationErrors">
<span class="label label-important" data-bind="text: $data.entityAspect.getValidationErrors('Country_Code')[0].errorMessage ">Important</span>
</div>
</td>
<td><input type="text" placeholder="Country Name" data-bind="value: Country_Name, uniqueName: true, valueUpdate: 'afterkeydown'"/>
<p data-bind="validationMessage: Country_Name"></p>
<span data-bind='visible: ko.computed(function() { debugger; }), text: Country_Name.validationMessage'> </span>
</td>
<td>
<span data-bind=' text: fullName'> </span>
</td>
<td >
<a class="btn btn-danger" data-bind="click: $root.cancel, visible: $data.IsModified" href="#" title="cancel/undo changes">Undo Changes<i class="icon-trash"></i></a>
<a class="btn btn-danger" data-bind="click: $root.remove, visible: !$data.IsDeleted() " href="#" title="Delete this Row">Delete<i class="icon-remove"></i></a>
<a class="btn btn-danger" data-bind="click: $root.UndoDelete, visible: $data.IsDeleted() " href="#" title="Undo Delete">Un Delete<i class="icon-remove"></i></a>
</td>
</tr>
</script>
Analysis
The propertyChanged event is raised when ... a property changes. But that's not what you want to watch. You want to monitor the entityAspect.entityState
When you set a property to a new value (for example person.FirstName("Naunihal")), you get both a propertyChanged event and a change to the entity's EntityState.
When you delete the entity, the entity's EntityState changes ... to "Deleted". But deleting doesn't change a property of the entity. Breeze does not consider the EntityState itself to be a property of the entity. Therefore, there is no propertyChanged notification.
Solution
Update Jan 12, 2013
I think more people will discover this solution if I rephrase the question that you asked so people understand that you want to listen for changes to EntityState.
So I moved my answer to a new SO question: "How can I detect a change to an entity's EntityState?". Hope you don't mind following that link.