I have html file , and JSON file . In html file , I have created textbox with button to enable the user to enter a course name . In JSON I have an array of course objects contains some information regarding the course .
I want to use Ajax with jQuery when the user enter a course and hit the button it should loop the array in json to check whether this value is found or not . If it is found then show the details of this course .
This is my trying .
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>Finding Course Details</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#btn').click(function() {
var result = $('#div1');
result.html('');
var data1 = $('#text1').val();
$.ajax({
url: 'course.json',
method: 'get',
data: data1,
dataType: 'json',
success: function(response) {
result.html('level: ' + response.course[0].level + '<br/>' + 'Theoretical hours :' + response.course[0].Theoretical + '<br/>' + 'Practical hours :' + response.course[0].Practical);
}
});
});
});
</script>
<style>
div.container {
width: 100%;
border: 1px solid gray;
}
header,
footer {
padding: 1em;
color: black;
background-color: white;
clear: left;
text-align: center;
}
nav {
float: left;
max-width: 160px;
margin: 0;
padding: 1em;
}
a:hover {
color: blue;
background-color: transparent;
text-decoration: underline
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul a {
text-decoration: none;
}
article {
margin-left: 170px;
border-left: 1px solid gray;
padding: 1em;
overflow: hidden;
}
</style>
</head>
<body>
<div class="container">
<header>
<img src="9.jpg" width="300" height="200" alt="">
</header>
<nav>
<ul>
<li>Main
</li>
<li>Courses
</li>
</ul>
</nav>
<article>
<h1>Course Details</h1>
<form>
Enter Course Name :
<br/>
<input type="text" id="text1">
<input type="button" id="btn" value="Get Course Details">
<br/>
</form>
<div id="div1"></div>
</article>
<footer>B</footer>
</div>
</body>
</html>
This is json code :
{
"course" : [
{
"name":"Computer Programming",
"level" : "level 1",
"Theoretical" : "4",
"Practical" : "2"
},
{
"name":"Web Technologies",
"level" : "level 2",
"Theoretical" : "2",
"Practical" : "2"
},
{
"name":"Project",
"level" : "level 4",
"Theoretical" : "2",
"Practical" : "2"
}
]
}
get the specific json by user entered data using $.grep
var data = {
"items": [{
"id": 1,
"category": "cat1"
}, {
"id": 2,
"category": "cat2"
}, {
"id": 3,
"category": "cat1"
}]
};
var returnedData = $.grep(data.items, function (element, index) {
return element.id == 1;
});
alert(returnedData[0].id + " " + returnedData[0].category);
Vanilla JavaScript solution:
var searchItem = "Web Technologies"
var jsonCourses = {
"course" : [
{
"name":"Computer Programming",
"level" : "level 1",
"Theoretical" : "4",
"Practical" : "2"
},
{
"name":"Web Technologies",
"level" : "level 2",
"Theoretical" : "2",
"Practical" : "2"
},
{
"name":"Project",
"level" : "level 4",
"Theoretical" : "2",
"Practical" : "2"
}
]
};
var details = jsonCourses.course.filter(function(i){
if(i.name === searchItem)return i
})
alert("Course:"+details[0].name+"|Level:"+details[0].level)
Related
I have 2 Vuetify data tables without pagination. Every row of the second one got exactly one parent in the first one. If I click on one of those entries in the second one, I want to search for the parent and jump to that row. All I found for now is filtering, but I only want to have that row on top of my table.
Is something like this possible?
We can't really help you without code, even if i've seen that you can't, it should be cool if you could modify some parts of your code like variables and datas ...
However, i'll try to do my best to explain
What you have to do is to reorder your data array binded on your table depending on a given id (or other data) to identify it.
I made a similar exemple of your needs, but i repeat i can't really be exhausitve :
Parent component:
<template>
<div id="app">
<listone :list="listOne" :toggled="toggledParent"></listone>
<listtwo :list="listTwo" v-model="toggledParent"></listtwo>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
toggledParent: 0,
listOne: [
{
id: 1,
title: "parent1",
},
{
id: 2,
title: "parent2",
},
{
id: 3,
title: "parent3",
},
],
listTwo: [
{
title: "title1",
parent: 3,
},
{
title: "title2",
parent: 1,
},
{
title: "title3",
parent: 2,
},
],
}),
components: {
listone: () => import("#/components/listone"),
listtwo: () => import("#/components/listtwo"),
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
</style>
ListOne component :
<template>
<div class="list">
<a v-for="item in treatedList" :key="item.title">
{{ item.title }}
</a>
</div>
</template>
<script>
export default {
name: "listone",
props: {
list: Array,
toggled: Number,
},
computed: {
treatedList: function () {
let tmp = this.list;
let $this = this
return tmp.sort(function (a, b) {
return a.id === $this.toggled ? -1 : b.id === $this.toggled ? 1 : 0;
});
},
},
};
</script>
<style>
.list {
display: flex;
flex-flow: column nowrap;
}
.list > a {
border: 1px solid red;
}
</style>
ListTwo component :
<template>
<div class="list">
<a
v-for="item in list"
:key="item.title"
#click="$emit('input', item.parent)">
{{ item.title }}
</a>
</div>
</template>
<script>
export default {
name: "listtwo",
props: {
list: Array,
toggledParent: Number
},
};
</script>
<style scoped>
.list {
display: flex;
flex-flow: column nowrap;
}
.list > a {
border: 1px solid red;
}
</style>
Try it and say me it helps you as wanted
Demo on codesandbox.io : https://codesandbox.io/s/mutable-thunder-zo8vn?fontsize=14&hidenavigation=1&theme=dark
So without knowing what your data looks like i'll use a standard array of objects without meta data.
What you could do, is use the sort function inside of computed property like below, this will re-organize your list every time you match or filter the list.
(Note: This re-arranges your entire list every time)
Here is a really basic example:
new Vue({
el: "#app",
data: {
search: 'Bananas',
tableData: [
{
item: "Cherries",
price: 3.99,
type: "Fruit"
},
{
item: "Chicken",
price: 6.99,
type: "Meat"
},
{
item: "Bananas",
price: 1.99,
type: "Fruit"
},
{
item: "Cola",
price: 0.99,
type: "Drink"
},
{
item: "Coffee",
price: 2.99,
type: "Drink"
},
]
},
computed: {
getTableData: function() {
return this.tableData.sort((x,y) => { return x.item == this.search ? -1 : y.item == this.search ? 1 : 0; });
}
}
})
table {
background: #ccc;
padding: 20px;
width:50%;
}
table tr {
background: #f1f1f1;
}
table tr td {
padding: 10px;
}
.firstRow {
background: green;
color:white;
}
.searchBar {
padding:20px;
width: 40%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="searchBar">
Search <input type="text" v-model="search">
</div>
<table>
<tr class="firstRow"><td>Item</td> <td>Price</td> <td>Type</td></tr>
<tr v-for="(product, index) in getTableData" :key="index">
<td>{{product.item}}</td>
<td>{{product.type}}</td>
<td>{{product.price}}</td>
</tr>
</table>
</div>
So the JSON I need to use is structured like this:
[
{
"result":"OK",
"message":"Display",
"value":200,
"rows":29
} ,
[
{
"personID":1,
"img_path":"/1234/",
"img":"00001.jpg"
},
{
"personID":2,
"img_path":"/1234/",
"img":"00002.jpg"
},
]
]
How do it get JUST this part?:
personID: 1
img_path: /1234/
img: 00001.jpg
Here's what I'm doing currently, which is outputs the full JSON... (exactly as it's shown in the first codeblock I added... the one that was showing how the JSON is structured).
var fullURL = the_URL_where_Im_getting_the_json
function readTextFile(file, callback)
{
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status == "200")
{
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
readTextFile(fullURL, function(text){
var data = JSON.parse(text);
console.log(data);
}
);
I appreciate you time and help. Thanks.
Trying to access this via indexes doesn't seem too robust. If you know the shape is going to be consistent with this type of output, you can deconstruct the data into info and results and then iterate over them. If you know what identifier you are looking for, for example, you can use find.
I have extended this example a bit to try to show how using functions like map and find can work over larger sets of data, as whatever project you are working on gets bigger. Front-end frameworks like React do a lot of this stuff for you.
const data = [{
"result": "OK",
"message": "Display",
"value": 200,
"rows": 29
},
[{
"personID": 1,
"img_path": "/1234/",
"img": "00001.jpg"
},
{
"personID": 2,
"img_path": "/1234/",
"img": "00002.jpg"
},
]
]
const [info, results] = data;
document.getElementById('information').innerHTML = Object.entries(info).map(([key, value]) => `
<div>
<span class="key">${key.toUpperCase()}:</span>
<span class="value">${value}</span>
</div>`).join('');
document.getElementById('results').innerHTML = results.map(result => {
return `<div>ID: ${result.personID}, path: ${result.img_path}</div>`
}).join('');
document.getElementById('find').addEventListener('keyup', function() {
document.getElementById('target').innerHTML = (results.find(result => result.personID == this.value) || {
img: 'Not Found'
}).img
})
.cards {
display: flex;
}
.card {
box-shadow: 1px 1px 10px;
padding: 16px;
width: 25%;
margin: 6px;
}
.card-title {
font-size: 2em;
border-bottom: 1px solid black;
padding: 6px 6px 6px 0px;
}
.card-content {
display: flex;
flex-direction: column;
align-items: space-between;
}
.card-content>div {
margin: 6px;
display: flex;
justify-content: space-between;
}
input {
width: 50px;
}
<div class="cards">
<div class="card">
<div class="card-title">
Information
</div>
<div id="information" class="card-content"></div>
</div>
<div class="card">
<div class="card-title">
All People
</div>
<div id="results" class="card-content"></div>
</div>
<div class="card">
<div class="card-title">
Find IMG
</div>
Person ID:
<input id="find" />
<div id="target" class="card-content" />
</div>
</div>
I really feel the data in your file should be modified for consistency.
For now you can do this:
//loop through this if you want data of all objects in the 2nd item i.e data[1][0...n]
var objectData = data[1][0]
var personID = objectData.personID
var img = objectData.img
var img_path = objectData.img_path
I'm having difficulty generating a json object in the below format from the data below. Fiddle
[ { Invoice:
{
headers: { date: "15-01-2020", buyer: "McDonalds", order: "145632"},
items: { name: "Big Mac", quantity: "5", rate: "20.00"},
items: { name: "Small Mac", quantity: "10", rate: "10.00"}
}
}
, { Invoice: { // Other invoices go here, I've used just one for this example} }
]
<div class="invoice">
<div class="header">
<div contenteditable data="date">15-Jan-2020</div>
<div contenteditable data="buyer">McDonalds</div>
<div contenteditable data="order">145632</div>
</div>
<div class="item">
<div contenteditable data="name">Big Mac</div>
<div contenteditable data="quantity">5</div>
<div contenteditable data="rate">20.00</div>
</div>
<div class="item">
<div contenteditable data="name">Small Mac</div>
<div contenteditable data="quantity">10</div>
<div contenteditable data="rate">10.00</div>
</div>
</div>
<button>Loop</button>
jQuery
var button = $("button")
button.on("click",function() {
jsonObj =[];
$('.invoice>.header>div, .invoice>.item>div').each(function(index,item) {
console.log($(this).parent().attr('class'));
console.log($(this).attr('data'),$(this).text());
q = {}
q ['header'] = $(this).parent().attr('class');
q [$(this).attr('data')] = $(this).text();
jsonObj.push(q);
});
console.log(jsonObj);
console.log(JSON.stringify(jsonObj));
});
I current end up with an object like this where the keys are repeated everywhere. How can I get this right?
[ { "header": "header", "date": "15-Jan-2020"}
, { "header": "header", "buyer": "McDonalds"}
, { "header": "header", "order": "145632"}
, { "header": "item", "name": "Big Mac"}
, { "header": "item", "quantity": "5"}
, { "header": "item", "rate": "20.00"}
, { "header": "item", "name": "Small Mac"}
, { "header": "item", "quantity": "10"}
, { "header": "item", "rate": "10.00"}
]
In your example, you have an object with two same keys:
"items":{
"name":"Big Mac",
"quantity":"5",
"rate":"20.00"
}
"items":{
"name":"Small Mac",
"quantity":"10",
"rate":"10.00"
}
This won't work, because you can only have one, so you need to change the value of items key to an array of objects:
"items":[
{
"name":"Big Mac",
"quantity":"5",
"rate":"20.00"
},
{
"name":"Small Mac",
"quantity":"10",
"rate":"10.00"
}
]
The iteration code may look like this:
const jsonObj = [];
$('.invoice').each((index, item) => {
const invoice = {
header: {},
items: []
};
$(item).find('.header > div').each((index, item) => {
const key = $(item).attr('data');
invoice.header[key] = $(item).text();
});
$(item).find('.item').each((index, item) => {
const itemObj = {};
$(item).find('div').each((index, item) => {
const key = $(item).attr('data');
itemObj[key] = $(item).text();
});
invoice.items.push(itemObj);
});
jsonObj.push({
Invoice: invoice
});
});
The main difference from your version is that it iterates through the dom step by step. First, through each invoice, then through each header of the invoice and each item. This way it's easy to build the desired structure.
Here's the jsfiddle link: https://jsfiddle.net/tara5/tanb174h/
Pure JS code for this:
Remarks : I have changed:
<div ... data="..."> ... </div>
to
<div ... data-ref="..."> ... </div>
to be conform with HTML directives (see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-* )
const jsonObj = []
, inVoices = document.querySelector('.invoice')
, subDivOf = (parent,query) => [...parent.querySelectorAll(query)]
, dataElms = (ac,el)=>{ac[el.dataset.ref]=el.textContent;return ac }
;
Loop.onclick=_=>
{
jsonObj.push( { Invoice: getInVoicesValues() } )
console.clear()
console.log( jsonObj )
}
function getInVoicesValues()
{
const headers = subDivOf(inVoices,'.header>div').reduce(dataElms,{})
, items = subDivOf(inVoices,'.item').reduce((accI,itm)=>
{
accI.push( subDivOf(itm, 'div').reduce(dataElms,{}))
return accI
},[])
;
return { headers, items }
}
.as-console-wrapper {
max-height: 100% !important;
width: 70% !important;
top: 0; left: 30% !important;
}
div.invoice>div:before {
display: block;
content: attr(class) ' :';
}
div[contenteditable] {
font: 12px Arial, Helvetica, sans-serif;
margin: .3em;
width: 12em;
border : 1px solid grey;
padding:.2em 1em;
margin-left:6em;
}
div[contenteditable]::before {
display: inline-block;
content: attr(data-ref);
font-weight : bold;
width: 4.9em;
margin-left:-5.3em;
}
<div class="invoice">
<div class="header">
<div contenteditable data-ref="date">15-Jan-2020</div>
<div contenteditable data-ref="buyer">McDonalds</div>
<div contenteditable data-ref="order">145632</div>
</div>
<div class="item">
<div contenteditable data-ref="name">Big Mac</div>
<div contenteditable data-ref="quantity">5</div>
<div contenteditable data-ref="rate">20.00</div>
</div>
<div class="item">
<div contenteditable data-ref="name">Small Mac</div>
<div contenteditable data-ref="quantity">10</div>
<div contenteditable data-ref="rate">10.00</div>
</div>
</div>
<button id="Loop">Loop</button>
.........................run snippets full screen for better view
second method
const jsonObj = [];
const inVoicesElms = document.querySelectorAll('.invoice div');
Loop.onclick=_=>
{
jsonObj.push( { Invoice: getInVoicesValues() } )
console.clear()
console.log( jsonObj )
}
function getInVoicesValues()
{
let rep = { headers:{}, items:[] }
, cur = null
;
inVoicesElms.forEach(el =>
{
if (el.matches('.header'))
{
cur = rep.headers
}
else if (el.matches('.item'))
{
cur = {}
rep.items.push(cur)
}
else // (el.matches('[contenteditable]'))
{
cur[el.getAttribute('data')] = el.textContent
}
})
return rep
}
.as-console-wrapper { max-height: 100% !important; width: 70% !important;
top: 0; left: 30% !important;
}
<div class="invoice">
<div class="header">
<div contenteditable data="date">15-Jan-2020</div>
<div contenteditable data="buyer">McDonalds</div>
<div contenteditable data="order">145632</div>
</div>
<div class="item">
<div contenteditable data="name">Big Mac</div>
<div contenteditable data="quantity">5</div>
<div contenteditable data="rate">20.00</div>
</div>
<div class="item">
<div contenteditable data="name">Small Mac</div>
<div contenteditable data="quantity">10</div>
<div contenteditable data="rate">10.00</div>
</div>
</div>
<button id="Loop">Loop</button>
How to stop hiding the treeview when the expand/collapse icon was clicked? But clicking the name/item in the treeview should hide the treeview. Below is the sample implementation where a dropdownlist will show/hide a treeview with searchbox. when I click the searchbox the treeview component should remain showing same goes while clicking the expand/collapse icon. But when I click the item the treeview it should hide. When I hover outside the treeview component, it should hide. The list item is dynamically created inside the component. I tried to pass the event, in the click event for list item element, and I called the event.stopPropagation but it's not working. Any ideas?
dropdowntreeview.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Demo angular-tree-dropdown</title>
<link rel='stylesheet' href="dropdowntreeview.css" />
<link rel='stylesheet' href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<link rel='stylesheet' href="dropdowntreeview.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" ></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js" ></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js" ></script>
<script src="dropdowntreeview.js"></script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="myController" class="dropdown dropdown-scroll">
<div class="btn btn-default dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" style="margin:10px 0 30px 0; padding:10px; background-color:#EEEEEE; border-radius:5px; font:12px Tahoma;">
<span><b>Selected Node</b> : {{mytree.currentNode.roleName}}</span>
</div>
<div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<input ng-model='treeSearchQuery' type="text" placeholder="Search in tree..."/>
<div
data-angular-treeview="true"
data-tree-id="mytree"
data-tree-model="roleList"
data-node-id="roleId"
data-node-label="roleName"
data-node-children="children"
data-search-query='treeSearchQuery'>
</div>
</div>
</div>
</div>
<body>
</html>
dropdowntreeview.js
(function(){
//angular module
var myApp = angular.module('myApp', ['angularTreeview']);
//test controller
myApp.controller('myController', function($scope){
//test tree model 2
$scope.roleList2 = [
{ "roleName" : "User default expanded", "roleId" : "role1", "expanded" : true, "children" : [
{ "roleName" : "subUser1 non-openable folder", "roleId" : "role11" },
{ "roleName" : "subUser2", "roleId" : "role12", "expanded" : true, "children" : [
{ "roleName" : "subUser2-1", "roleId" : "role121", "expanded" : true, "children" : [
{ "roleName" : "subUser2-1-1 folder ico", "roleId" : "role1211" },
{ "roleName" : "subUser2-1-2 file ico", "roleId" : "role1212" , "fileicon" : true}
]}
]}
]},
{ "roleName" : "Admin default collapsed", "roleId" : "role2", "children" : [
{ "roleName" : "subAdmin1", "roleId" : "role11", "children" : [] },
{ "roleName" : "subAdmin2", "roleId" : "role12", "children" : [
{ "roleName" : "subAdmin2-1", "roleId" : "role121", "children" : [
{ "roleName" : "subAdmin2-1-1", "roleId" : "role1211", "children" : [] },
{ "roleName" : "subAdmin2-1-2", "roleId" : "role1212", "children" : [] }
]}
]}
]}
];
//roleList1 to treeview
$scope.roleList = $scope.roleList2;
$('.dropdown-menu').find('input').click(function (e) {
e.stopPropagation();
});
});
})();
(function(angular) {
'use strict';
angular.module('angularTreeview', []).directive('treeModel', ['$compile', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var treeId = attrs.treeId;
var treeModel = attrs.treeModel;
var nodeId = attrs.nodeId;
var nodeLabel = attrs.nodeLabel;
var nodeChildren = attrs.nodeChildren;
var searchQuery = attrs.searchQuery;
var template = '<ul>' + '<li data-ng-repeat="node in ' + treeModel +
' | filter:' + searchQuery + ' ">' +
'<i class="collapsed" data-ng-class="{nopointer: !node.' +
nodeChildren + '.length}"' +
'data-ng-show="!node.expanded && !node.fileicon" data-ng-click="' +
treeId + '.selectNodeHead(node,event)"></i>' +
'<i class="expanded" data-ng-show="node.expanded && !node.fileicon" data-ng-click="' +
treeId + '.selectNodeHead(node)"></i>' +
'<i class="normal" data-ng-show="node.fileicon"></i> ' +
'<span title="{{node.' + nodeLabel + '}}" data-ng-class="node.selected" data-ng-click="' +
treeId + '.selectNodeLabel(node)">{{node.' + nodeLabel + '}}</span>' +
'<div data-ng-show="node.expanded" data-tree-id="' +
treeId + '" data-tree-model="node.' + nodeChildren +
'" data-node-id=' + nodeId + ' data-node-label=' + nodeLabel +
' data-node-children=' + nodeChildren + ' data-search-query=' +
searchQuery + '></div>' + '</li>' + '</ul>';
if (treeId && treeModel) {
if (attrs.angularTreeview) {
scope[treeId] = scope[treeId] || {};
scope[treeId].selectNodeHead = scope[treeId].selectNodeHead || function(selectedNode,event) {
//below code is not working!
event.stopPropagation();
if (selectedNode[nodeChildren] !== undefined) {
selectedNode.expanded = !selectedNode.expanded;
}
};
scope[treeId].selectNodeLabel = scope[treeId].selectNodeLabel || function(selectedNode) {
if (scope[treeId].currentNode && scope[treeId].currentNode.selected) {
scope[treeId].currentNode.selected = undefined;
}
selectedNode.selected = 'selected';
scope[treeId].currentNode = selectedNode;
};
}
element.html('').append($compile(template)(scope));
}
}
};
}]);
})(angular);
dropdowntreeview.css
div[data-angular-treeview] {
/* prevent user selection */
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
/* default */
font-family: Tahoma;
font-size:13px;
color: #555;
text-decoration: none;
}
div[data-tree-model] ul {
margin: 0;
padding: 0;
list-style: none;
border: none;
overflow: hidden;
}
div[data-tree-model] li {
position: relative;
padding: 0 0 0 20px;
line-height: 20px;
}
div[data-tree-model] li .expanded {
padding: 1px 10px;
background-image: url("collapse-icon.png");
background-repeat: no-repeat;
}
div[data-tree-model] li .collapsed {
padding: 1px 10px;
background-image: url("expand-icon.png");
background-repeat: no-repeat;
}
div[data-tree-model] li .normal {
padding: 1px 10px;
background-image: url("");
background-repeat: no-repeat;
}
div[data-tree-model] li i, div[data-tree-model] li span {
cursor: pointer;
}
div[data-tree-model] li .selected {
background-color: #aaddff;
font-weight: bold;
padding: 1px 5px;
}
.dropdown.dropdown-scroll .dropdown-menu {
max-height: 200px;
width: 60px;
overflow: auto;
}
You have to add $event as input parameter when invoking the selectNodeHead function.
From your code (refactored, just for human readablity, with backtick approach:
var template = `
<ul>
<li data-ng-repeat="node in ${treeModel} | filter: ${searchQuery}">
<i
class="collapsed"
data-ng-class="{nopointer: !node.${nodeChildren}.length}"
data-ng-show="!node.expanded && !node.fileicon"
data-ng-click="${treeId}.selectNodeHead(node, $event)"
></i>
<i
class="expanded"
data-ng-show="node.expanded && !node.fileicon"
data-ng-click="${treeId}.selectNodeHead(node, $event)"
></i>
<i
class="normal"
data-ng-show="node.fileicon"
></i>
<span
title="{{ node.${nodeLabel} }}"
data-ng-class="node.selected"
data-ng-click="${treeId}.selectNodeLabel(node)"
>{{ node.${nodeLabel} }}</span>
<div
data-ng-show="node.expanded"
data-tree-id="${treeId}"
data-tree-model="node.${nodeChildren}"
data-node-id="${nodeId}"
data-node-label="${nodeLabel}"
data-node-children="${nodeChildren}"
data-search-query="${searchQuery}"
></div>
</li>
</ul>
`;
Hope it helps.
Could anyone point me a more easy-to-read-and-expand way of doing this:
data = {/*very very long json*/};
var inHTML = "";
jQuery.each(data, function(key, value){
var articleUrl = 'url-to-somewhere';
var newItem = "<div class='item'><div class='item--poster'><img src='"+data[key].backdropUrl+"' alt='title'/></div><div class='item--content'><h2>"+data[key].title+"</h2><ul><li>"+data[key].productionYear+"</li><li>"+data[key].productionCountry+"</li></ul></div><div class='item--link'><p><a class='' href='"+articleUrl+"'>Lue lisää</a></p></div></div>";
inHTML += newItem;
});
jQuery("#container").html(inHTML);
What I'm looking for is something similar to ng-repeat of Angular.
I would bet on using placeholder template and .clone(). What exactly you need to do is, create a Master DOM like this:
<div id="master-dom" class="item">
<p><strong>Name</strong> <span class="Name"></span></p>
<p><strong>Age</strong> <span class="Age"></span></p>
</div>
Now give a CSS that would hide the Master DOM:
#master-dom {display: none;}
The next attempt would be, have a #content area:
<div id="content"></div>
And now comes the JavaScript part.
var data = [
{
"name": "Praveen",
"age": 27
},
{
"name": "Jon Skeet",
"age": 29
},
{
"name": "Kumar",
"age": 25
}
];
Having the above as the data structure, you can loop through and insert:
$.each(data, function (i, v) {
// We need the v.
$("#master-dom").clone()
.removeAttr("id")
.find(".Name").text(v.name).end()
.find(".Age").text(v.age).end()
.appendTo("#content");
});
See the final output here:
$(function() {
var data = [{
"name": "Praveen",
"age": 27
}, {
"name": "Jon Skeet",
"age": 29
}, {
"name": "Kumar",
"age": 25
}];
$.each(data, function(i, v) {
// We need the v.
$("#master-dom").clone()
.removeAttr("id")
.find(".Name").text(v.name).end()
.find(".Age").text(v.age).end()
.appendTo("#content");
});
});
* {
margin: 0;
padding: 0;
list-style: none;
}
#master-dom {
display: none;
}
.item p strong {
display: inline-block;
width: 75px;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div id="master-dom" class="item">
<p><strong>Name</strong> <span class="Name"></span></p>
<p><strong>Age</strong> <span class="Age"></span></p>
</div>
<div id="content"></div>
I really believe this would be the underlying logic behind Angular's ng-repeat. Also I would use this above logic if I were in your place.
You could use ES6 feature Template literals
Your string would look like this
var newItem =
`<div class='item'>
<div class='item--poster'>
<img src='${data[key].backdropUrl}' alt='title'/>
</div>
<div class='item--content'>
<h2>${data[key].title}</h2>
<ul>
<li>${data[key].productionYear}</li>
<li>${data[key].productionCountry}</li>
</ul>
</div>
<div class='item--link'>
<p>
<a class='' href='${articleUrl}'>Lue lisää</a>
</p>
</div>
</div>`;