I am building a partial view, where I have to hide a button depending on a value from the main view, the columns hides them well, but when hiding the button it does not work.
I have the following function
function onSelect(e) {
gridEstudiantesShowHide(false);
if ($('input[name="hd_idServicio"]').val($("#ddlServicios").val()) != "") {
if ($("#ddlServicios").val().split("#")[4] === "0") {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(4);
}
else {
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(4);
}
if ($("#ddlServicios").val().split("#")[2] == "4" || $("#ddlServicios").val().split("#")[2] == "9") {
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(5);
}
else {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(5);
}
if ($("#ddlServicios").val().split("#")[3] == "1") {
var grid = $("#Grid").data("kendoGrid");
grid.hideColumn(3);
columns: [
{ field: "name" },
{ command: [{ name: "AsignarGrupo", visible: false}] }
]
}
else {
console.log("Muestra botón");
var grid = $("#Grid").data("kendoGrid");
grid.showColumn(3);
{ command: [{ name: "AsignarGrupo", visible: false}] }
}
}
else {
}
it only works when hiding columns, and I have read all the dojo documentation to no avail.
Someone could help me?
The property visible in the column's command expects a function which have to return a boolean, so you can do this in your column definition:
{ command: [{ name: "AsignarGrupo", visible: function(dataItem) { return $("\\#ddlServicios").val().split("\\#")[3] == "1"; } }] }
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default-v2.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.1.330/js/kendo.all.min.js"></script>
</head>
<body>
<select id="ddlServicios">
<option value="1#1#1#1">Opt 1</option>
</select>
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ command: "destroy" }, // displays the built-in "destroy" command
{ command: [{ name: "test", visible: function(dataItem) { return $("\\#ddlServicios").val().split("\\#")[3] == "1"; } }] }
],
editable: true,
dataSource: [ { name: "Jane Doe" } ]
});
</script>
</body>
</html>
Dojo
I have a list of documents with a checkbox next to each. Clicking on a checkbox is supposed to append that document to a separate div (aka a "Favorites List"). This does not work, but clicking on the div that surrounds the checkbox appends that document correctly. Another issue is that clicking on a checkbox when the Favorites contains one or more documents clears the list.
How can I properly register the checkbox itself to the click event rather than the div surrounding the checkbox? I've tried different methods, such as
$( "input[type='checkbox']" ).on("click", faveFunc), but I've been coming up short so I thought I'd ask about it here.
JS snippet:
import $ from 'jquery';
var tableRes = '';
export default class {
constructor() {
this.loadTableData();
}
// this area contains code that's irrelevant //
// ------ Rendering checkboxes ------- //
$("#km-table-id tbody tr").on("click", function(evt) {
evt.stopPropagation();
if (evt.target.type !== "checkbox") {
$(":checkbox", this).on("click");
}
});
// ------ Appending checkboxes ------- //
let inputType = $("<input />", {"type": "checkbox"})
let chkboxCol = $("#km-table-id tbody tr > td:nth-child(3)");
chkboxCol.append(inputType).addClass("checkbox-class");
// --- My Favorites functionality ---- //
function faveFunc(evt) {
let anchor = $($(evt.target).prev().find("a")[0]).clone();
// let ancTxt = $(anchor).text();
switch($(".populate-faves").find("a:contains(" + $(anchor).text() + ")").length)
{
case 0:
$(".populate-faves").append(anchor);
break;
default:
$(".populate-faves > a:contains(" + $(anchor).text() + ")").remove();
break;
}
};
function newList() {
let data = $(evt.target).prev().find("a").eq(0).html();
let outputList = $(".populate-faves");
$(".populate-faves").html("");
$("#km-table-id tbody tr)").each(function(i, el) {
let cntxFave = $(".add-id", el);
let fave = $(".checkbox-class", el);
let itemText = $(data, el);
if(cntxFave.is(".add-id")) {
outputList.append("<li>" + itemText.html() + "</li>");
}
if(fave.prop("checked")) {
outputList.append("<li>" + itemText.html() + "</li>");
}
});
}; // ------------ newList
$(".checkbox-class").on("click", faveFunc);
HTML snippet:
<div class="col-md-14"> <!-- Right -->
<table id="km-table-id" class="cell-border display stripe-hover">
<thead>
<tr>
<!-- <th></th> -->
<th></th>
<th></th>
<th>Title</th>
<th></th> <!-- Keep here--this is for checkbox col -->
</tr>
</thead>
<tbody></tbody>
</table>
import $ from 'jquery';
import dt from 'datatables.net';
var categories = '';
var tableRes = '';
export default class {
constructor() {
this.loadCategoryData();
this.loadTableData();
}
let KMdocs = {
{
"d": {
"results": [
{
"__metadata": {
"id": "[redacted]",
"uri": "[redacted]",
"etag": "\"2\"",
"type": "[redacted]"
},
"File": {
"__metadata": {
"id": "[redacted]",
"uri": "[redacted]",
"type": "SP.File"
},
"Name": "Guide to Product IDs.docx"
},
"FileLeafRef": "Guide to Product IDs.docx",
"ResourceType": {
"__metadata": {
"type": "Collection(SP.Taxonomy.TaxonomyFieldValue)"
},
"results": [
{
"Label": "Guides \uff06 Protocols",
"TermGuid": "[redacted]",
"WssId": 706
}
]
},
"EncodedAbsUrl": "[redacted]"
},
{
"__metadata": {
"id": "[redacted]",
"uri": "[redacted]",
"etag": "\"3\"",
"type": "SP.Data.KMDocumentsItem"
},
"File": {
"__metadata": {
"id": "[redacted]",
"uri": "[redacted]",
"type": "SP.File"
},
"Name": "LRRP Template 1.docx"
},
"FileLeafRef": "LRRP Template 1.docx",
"ResourceType": {
"__metadata": {
"type": "Collection(SP.Taxonomy.TaxonomyFieldValue)"
},
"results": [
{
"Label": "Templates",
"TermGuid": "[redacted]",
"WssId": 941
},
{
"Label": "Guides \uff06 Protocols",
"TermGuid": "[redacted]",
"WssId": 706
}
]
},
"EncodedAbsUrl": "[redacted]"
},
{
"__metadata": {
"[redacted]",
"uri": "[redacted]",
"etag": "\"3\"",
"type": "SP.Data.KMDocumentsItem"
},
"File": {
"__metadata": {
"id": "[redacted]",
"uri": "[redacted]",
"type": "SP.File"
},
"Name": "LRRP Template 2.docx"
},
"FileLeafRef": "LRRP Template 2.docx",
"ResourceType": {
"__metadata": {
"type": "Collection(SP.Taxonomy.TaxonomyFieldValue)"
},
"results": [
{
"Label": "Templates",
"TermGuid": "[redacted]",
"WssId": 941
},
{
"Label": "Guides \uff06 Protocols",
"TermGuid": "[redacted]",
"WssId": 706
}
]
},
"EncodedAbsUrl": "[redacted]"
}
]
}
}
}
// ------ Loading Category data ------ //
loadCategoryData() {
let res = KMdocs.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
"FileName": obj.FileLeafRef,
"Titles": obj.File.Name,
"Path": obj.EncodedAbsUrl,
"Categories": obj.ResourceType.results.map(function(val) {
return val.Label;
}).join(";")
};
});
let label = KMdocs.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return obj.ResourceType.results.map(function(val) {
return val.Label;
})
});
// ---------- Unique Categs. --------- //
let unique = [];
let temp = KMdocs.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).forEach(function(obj) {
obj.ResourceType.results.forEach(function(val) {
let divCat = document.createElement("div");
$(divCat).attr("category", encodeURIComponent(val.Label));
$(divCat).html(val.Label);
if (!unique.includes(divCat.outerHTML)) {
unique.push(divCat.outerHTML); // value can be anything, only keys matter
}
})
});
let categories = unique.sort();
$(".indiv-label").append(categories);
} // ------------- loadCategoryData()
// ------ Loading doc title data ----- //
loadTableData() {
// Local icons exist under /SiteAssets/images, if needed //
function docType(fileName) {
let docImg = "<img src='[redacted]/Current.ashx/docx.gif' />"
let msgImg = "<img src='[redacted]/Current.ashx/msg.gif' />"
let nrlImg = "<img src='[redacted]/Current.ashx/nrl.gif' />"
let pdfImg = "<img src='[redacted]/Current.ashx/pdf.gif' />"
let pptImg = "<img src='[redacted]/Current.ashx/pptx.gif' />"
let xlsImg = "<img src='[redacted]/Current.ashx/xls.gif' />"
let docStr = fileName.split(".") // .split() seems to be necessary to render the icons
for (var i = 0; i < docStr.length; i++) {
if (docStr[i].includes('doc')) {
return docStr[i] = docImg;
} // -
else if (docStr[i].includes('DOCX')) {
return docStr[i] = docImg;
} // -
else if (docStr[i].includes('rtf')) {
return docStr[i] = docImg;
} // -
else if (docStr[i].includes('msg')) {
return docStr[i] = msgImg;
} //
else if (docStr[i].includes('nrl')) {
return docStr[i] = nrlImg;
} //
else if (docStr[i].includes('pdf')) {
return docStr[i] = pdfImg;
} //
else if (docStr[i].includes('ppt')) {
return docStr[i] = pptImg;
} // -
else if (docStr[i].includes('PPT')) {
return docStr[i] = pptImg;
} // -
else if (docStr[i].includes('potx')) {
return docStr[i] = pptImg;
} // -
else if (docStr[i].includes('xls')) {
return docStr[i] = xlsImg;
} //
}
} // docType
$.noConflict();
let tableRes = KMdocs.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
"Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name,
"Categories": obj.ResourceType.results.map(function(val) {
return val.Label;
}).join(";"),
"Blank": "", // use to create an empty column, if necessary
"docImg": docType(obj.File.Name) // Icon
}
})
// --------- Rendering table --------- //
$('#km-table-id').DataTable({
data: tableRes,
columns: [{
data: "Categories"
}, // available but hidden
{
data: "docImg",
sortable: false
}, // hides sorting arrows in icon col
{
data: "Titles"
},
{
data: "Blank",
sortable: false
}
],
columnDefs: [{
data: "Path",
ordering: true,
targets: [2],
render: function(data, type, row) {
return $('<a>')
.attr({
target: "_blank",
href: row.Path
})
.text(data)
.wrap('<div></div>')
.parent()
.html();
},
},
{
searchable: true,
targets: [0],
visible: false
}, // hides Categories col
],
language: {
searchPlaceholder: "Search All Documents"
},
lengthMenu: [10, 25, 50, 100, 250, 500],
order: [],
pageLength: 500, // showing multiple pgs doesn't render all checkboxes...but initially showing all items renders them
paging: true,
pagingType: "full_numbers",
responsive: true,
scrollCollapse: true,
scrollXInner: true,
scrollY: 550,
sDom: '<"top">rt<"bottom"flp><"left">' // affixes dropdown on bottom
});
// ------ Rendering checkboxes ------- //
$("#km-table-id tbody tr").on("click", function(evt) {
evt.stopPropagation();
if (evt.target.type !== "checkbox") {
$(":checkbox", this).on("click");
}
});
// ------ Appending checkboxes ------- //
let inputType = $("<input />", {
"type": "checkbox"
})
let chkboxCol = $("#km-table-id tbody tr > td:nth-child(3)");
chkboxCol.append(inputType).addClass("checkbox-class");
// --- My Favorites functionality ---- //
function faveFunc(evt) {
let anchor = $($(evt.target).prev().find("a")[0]).clone();
switch ($(".populate-faves").find("a:contains(" + $(anchor).text() + ")").length) {
case 0:
$(".populate-faves").append(anchor);
break;
default:
$(".populate-faves > a:contains(" + $(anchor).text() + ")").remove();
break;
}
};
function newList() {
let data = $(evt.target).prev().find("a").eq(0).html();
let outputList = $(".populate-faves");
$(".populate-faves").html("");
$("#km-table-id tbody tr)").each(function(i, el) {
let cntxFave = $(".add-id", el);
let fave = $(".checkbox-class", el);
let itemText = $(data, el);
if (cntxFave.is(".add-id")) {
outputList.append("<li>" + itemText.html() + "</li>");
}
if (fave.prop("checked")) {
outputList.append("<li>" + itemText.html() + "</li>");
}
});
}; // ------------ newList
$(":checkbox").on("click", faveFunc);
$("#add-id").on("click", faveFunc); // does not work
// Linking custom search w/ DT search //
let oTable = $("#km-table-id").DataTable();
$("#searchbar").on("input", function() {
oTable.search($(this)
.val() + " " + decodeURIComponent($(this)
.attr("category"))).draw();
})
} // ------------------ loadTableData
} // ------------- export default class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1, shrink-to-fit=no">
<title>Pages - KM</title>
<meta name="description" content="description here">
<meta name="keywords" content="keywords,here">
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.2.7/css/select.dataTables.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedheader/3.1.5/css/fixedHeader.dataTables.min.css">
<link rel="stylesheet" href="KMStyles.css" type="text/css">
<!-- jQuery first, then Popper.js -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<!------------------------------->
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" defer></script>
<script type="text/javascript" src="https://cdn.datatables.net/select/1.2.7/js/dataTables.select.min.js"></script>
<!------------------------------->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.2/core.min.js"></script>
<script type="text/javascript" src="SiteAssets/scripts/getListItems.js"></script>
</head>
<body>
<script src="./bundle.js"></script>
<div class="km-div-container">
<div class="col-md-3">
<!-- Left -->
<span class="KM-title"><h1>KM</h1></span>
<div class="form-group">
<input category="" class="form-control" daysprior="" id="searchbar" input-all="" placeholder="Search All Documents..." type="search">
</div>
<div id="myFave.hs-gc-header" class="faves-div">
<p style="font-weight:bold">My Favorites:</p>
<div class="populate-faves"></div>
<!-- location of favorited documents -->
</div>
</div>
<!-------------------------------------------->
<div class="col-md-3" id="middle-id">
<!-- Middle -->
<p>
<div class="all-docs-title" category="" style="font-weight:bold; cursor:pointer" input="">All Documents</div>
</p>
<p>
<div class="recently-added-title" category="" days="30" style="cursor:pointer;">Recently Added and/or Modified</div>
</p>
<div id="km-labels">
<a>
<p class="indiv-label" style="cursor:pointer;"></p>
</div>
</div>
<!-------------------------------------------->
<div class="col-md-14">
<!-- Right -->
<table id="km-table-id" class="cell-border display stripe-hover">
<thead>
<tr>
<!-- <th></th> -->
<th></th>
<th></th>
<th>Title</th>
<th></th>
<!-- Keep here--this is for checkbox col -->
</tr>
</thead>
<tbody></tbody>
</table>
<!-- <ul class="custom-menu">
<li data-action="open" id="open-id">Open Document</li>
<li data-action="add" id="add-id">Set As Favorite</li>
<li data-action="email">Email Document</a></li>
</ul> -->
</div>
<!-- col-md-14 -->
<!-- <div class="kmdialog"></div> -->
<!-- what is this? -->
</div>
<!-- km-div-container -->
</body>
</html>
The core of the demo is the following:
event.type ⇩ Event Handler ⇩
$(document).on('change', 'CHECKBOX', addFav);
⇧ event.currentTarget ⇧ event.target
Demo Outline
Assign each checkbox a data-* attribute with a unique value. ex. data-id="1"
To reference and clone an element in a table cell placed before the table cell with the checkbox, ex.:
$(event.target).closest('td').prev('td').find(ANCHOR).clone();
Use the data-* attribute of the checkbox to associate it with the cloned element in the example below the cloned anchor is appended to a <li>, ex.:
$(LI).addClass('fav'+ID).append(ANCHOR);
The association is used to remove the <li> from the favorites list when the checkbox is unchecked, ex.:
$('.fav'+ID).remove();
Review demo in full page mode
<!DOCTYPE html>
<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet">
<style>
caption {
caption-side: top;
font-size: 1.5rem;
font-weight: 400
}
.favorite {
list-style: none
}
.favorite li::before {
content: '\1f49a\a0\a0'
}
</style>
</head>
<body>
<header class="container">
<section class='row'>
<fieldset class="col-md-12">
<legend>💖 Favorites:</legend>
<ul class='favorite'></ul>
</fieldset>
</section>
</header>
<hr>
<main class='container'>
<section class='row'>
<article class="col-md-12">
<table class='table'>
<caption>Data</caption>
<thead>
<tr>
<th></th>
<th>Link</th>
<th>Title</th>
<th></th>
</tr>
</thead>
<tbody class='table-bordered'>
<tr>
<td></td>
<td>
<a href='#/' class='lnx'>LINK 1: Category I</a></td>
<td>
<label class="custom-control custom-checkbox">
<input class="chx custom-control-input" type="checkbox" data-id='1'>
<b class="custom-control-indicator"></b>
<b class="custom-control-description"> 💙</b>
</label>
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
<a href='#/' class='lnx'>LINK 2: Category II</a></td>
<td>
<label class="custom-control custom-checkbox">
<input class="chx custom-control-input" type="checkbox" data-id='2'>
<b class="custom-control-indicator"></b>
<b class="custom-control-description"> 💙</b>
</label>
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
<a href='#/' class='lnx'>LINK 3: Category III</a></td>
<td>
<label class="custom-control custom-checkbox">
<input class="chx custom-control-input" type="checkbox" data-id='3'>
<b class="custom-control-indicator"></b>
<b class="custom-control-description"> 💙</b>
</label>
</td>
<td></td>
</tr>
</tbody>
</table>
</article>
</section>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).on('change', '.chx', addFav);
function addFav(e) {
var tgt = e.target;
var ID = $(tgt).data('id');
if (tgt.checked) {
var lnx = $(tgt).closest('td').prev('td').find('.lnx').clone();
var item = document.createElement('li');
$('.favorite').append(item);
$(item).addClass('fav' + ID).append(lnx);
return false;
} else if (!tgt.checked) {
$('.fav' + ID).remove();
}
}
</script>
</body>
</html>
I need, based on an in page variable, to change value of a binding element.
Here it is the in page var:
<script type="text/javascript">
var myVar = 'value1';
</script>
This is the select with the bind element:
<select value="">
<option ng-repeat="value in valueList">
{{myNewValue()}}
</option>
</select>
Here is the controller:
$scope.inPageVar = $window.myVar;
$http.get(jsonUrl).then(function(result) {
$scope.valueList = result.data.valueList;
$scope.myNewValue = function() {
return $scope.valueList[0].additional + $scope.inPageVar;
};
});
Here the JSON structure:
"valueList": [
{
"additionnal": {
"value1": "this is value 1",
"value2": "this is value 2"
}
},
{
"additionnal": {
"value1": "this is value 3",
"value2": "this is value 4"
}
}
]
I would like to know how to concatenate the in-page var value with the element of the get function.. Thank you!
(function() {
angular.module("CombineModule", []).controller('MyController', function() {
this.values = [{
"additional": {
"value1": "this is value 1",
"value2": "this is value 2"
}
}, {
"additional": {
"value1": "this is value 3",
"value2": "this is value 4"
}
}];
this.myNewValue = function(index) {
return this.values[index].additional[myVar];
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en" ng-app="CombineModule">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
var myVar = 'value1';
</script>
</head>
<body ng-controller="MyController as v">
<select value="">
<option ng-repeat="value in v.values">
{{v.myNewValue($index)}}
</option>
</select>
<script src="app.js"></script>
</body>
</html>
If you want to expose myVar globally,
write window.myVar = 'some value' instead of var myVar = 'someval'.
Or if you want to make this available into $rootScope.myVar = 'some value'
Then in your logic,
return $scope.valueList[0].additional[window.myVar];
I am using angularjs. I have sample list of json. I am display the list using ng-repeat and I have checkbox in html.
I need to find user checkbox is clicked or not(not checked or not).
Here's a working example:
var app = angular.module('MyApp', []);
app.controller('MainCtrl', function($scope) {
$scope.result = {};
$scope.result.name = 'World';
var data = '[ { "button": 1, "name": "Test-1", "checked" : 0 }, { "button": 2, "name": "Test-2", "checked" : 0 }, { "button": 3, "name": "Test-3", "checked" : 1 }, { "button": 4, "name": "Test-4", "checked" : 0 }, { "button": 5, "name": "Test-5", "checked" : 1 } ]';
$scope.result.list = JSON.parse(data);
});
<script src="https://code.angularjs.org/1.4.9/angular.js"></script>
<div ng-app="MyApp" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>{{result.list.name}}
<ul>
<li ng-repeat="list in result.list">
<input type="checkbox" ng-model="list.isChecked" ng-checked="list.checked == 1">- {{list.name}}</li>
</ul>
</div>
Expected output:
Find user clicked the checkbox or not.
If checkbox already checked (3 & 5). If user unchecked means I need to identify.
Alternatively, here's a Plunker.
As far as I understood, You want to check if the checkbox was clicked by user or not. Check out the below code changes or on Plunker
This code adds, isClicked attribute to the check-boxes that were clicked. Also it stores the current value of check-boxes in checked attribute.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.result = {};
$scope.result.name = 'World';
var data = '[ { "button": 1, "name": "Test-1", "checked" : 0 }, { "button": 2, "name": "Test-2", "checked" : 0 }, { "button": 3, "name": "Test-3", "checked" : 1 }, { "button": 4, "name": "Test-4", "checked" : 0 }, { "button": 5, "name": "Test-5", "checked" : 1 } ]';
$scope.result.list = JSON.parse(data);
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>{{result.list}}
<ul>
<li ng-repeat="list in result.list">
<input type="checkbox" ng-model="list.checked" ng-click="list.isClicked = true" ng-true-value="1" ng-false-value="0">- {{list.name}}</li>
</ul>
</body>
</html>
I have a web page on which I would like to display dynamically a tree based on a JSON array with the help of jQuery. Each node of my tree has a checkbox associated to it. When I click a node which has children, I would like all of them to be checked. I’ve already taken care of printing the tree and the checkboxes and I am now trying to select children nodes and I am not able.
Below is the code (simplified) that I have so far. Does anybody has an idea how I could automatically check the children checkboxes when a checkbox is checked with jQuery?
Thanks!
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var myJSON = {
"d": {
"__type": "Branch",
"Name": "$",
"FullPath": "$\\$",
"SubBranch": [
{
"__type": "Branch",
"Name": "System",
"FullPath": "$\\System",
"SubBranch": [
{
"__type": "Branch",
"Name": "Library",
"FullPath": "$\\System\\Library",
"SubBranch": [
]
},
{
"__type": "Branch",
"Name": "Configuration",
"FullPath": "$\\System\\Configuration",
"SubBranch": [
{
"__type": "Branch",
"Name": "Reimage",
"FullPath": "$\\System\\Configuration\\Reimage",
"SubBranch": [
]
},
{
"__type": "Branch",
"Name": "Installation",
"FullPath": "$\\System\\Configuration\\Installation",
"SubBranch": [
]
}
]
},
]
}
]
}
}
var output;
var indentationLevel = 0;
function GetSpacing(numberOfSpaces) {
var tabs = '';
for (i = 0; i < numberOfSpaces; i++) {
tabs += ' ';
}
return tabs;
}
function GetHtmlForFeaturePath(featurePath) {
return '<div>' + GetSpacing(indentationLevel) + '<input type="checkbox" id="' + featurePath.FullPath + '" class="featureTreeCheckbox" />' + featurePath.Name + "</div>";
}
function GetHtmlForFeaturePaths(node) {
output += GetHtmlForFeaturePath(node);
indentationLevel++;
jQuery.each(node.SubBranch, function() {
GetHtmlForFeaturePaths(this);
});
indentationLevel--;
}
String.prototype.startsWith = function(str) {
return this.match("^" + str) == str;
}
window.onload = function() {
GetHtmlForFeaturePaths(myJSON.d);
document.writeln(output);
/* How do I tell a node to check its children? */
$('input').click(function(event) {
var clickedControlId = this.id;
alert(clickedControlId);
/* alert($.grep(myJSON.d, function (a) { return a.FullPath == clickedControlId })); */
});
}
</script>
</head>
<body>
jQuery
</body>
</html>
It is not a good practice to distinguish levels with spaces. Instead you should use a class or an id. This helps both the appearance (you can use css) and your code, since it defines logical levels.
Edit your code to produce a DOM like that:
<div class="level1">
<input id="$\$" class="featureTreeCheckbox" type="checkbox">$
<div class="level2">
<input id="$\System" class="featureTreeCheckbox" type="checkbox">System
<div class="level3">
<input id="$\System\Library" class="featureTreeCheckbox" type="checkbox">Library
</div>
<div class="level3">
<input id="$\System\Configuration" class="featureTreeCheckbox" type="checkbox">Configuration
<div class="level4">
<input id="$\System\Configuration\Reimage" class="featureTreeCheckbox" type="checkbox">Reimage<br/>
<input id="$\System\Configuration\Installation" class="featureTreeCheckbox" type="checkbox">Installation
</div>
</div>
</div>
</div>
Each "levelx" class defines a level. You can easily style it like this:
<style>
.level1 { margin-left: 0px; }
.level2 { margin-left: 10px; }
.level3 { margin-left: 20px; }
.level4 { margin-left: 30px; }
</style>
Then you can use code like this:
<script type="text/javascript">
$(function() {
$('div.level1 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find("input").attr("checked", "checked");
}
});
$('div.level2 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find(".level3 input").attr("checked", "checked");
$(this).parent().find(".level4 input").attr("checked", "checked");
}
});
$('div.level3 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find(".level4 input").attr("checked", "checked");
}
});
});
</script>
I'd simplify what kgiannakakis did:
$(function() {
$('div input:first').change(function(event) {
if ($(this).is(":checked")) {
$(this).next("div").find("input").attr("checked", "checked");
} else {
$(this).next("div").find("input").removeAttr("checked");
}
});
});
This should work for any number of levels.