Parsing JSON data from textarea with Javascript - javascript

I am trying to be able to drop JSON formatted data into a textarea to be able to pull out one piece of data at a time. Currently I am just trying to get the names output to a DIV. This is a static HTML file with one textarea, one button and 1 DIV. I am not getting any output which I do not understand. Any assistance would be greatly appreciated.
HTML
<!DOCTYPE html>
<html>
<head>
<script>
function parser(){
var results = document.getElementById("results");
var information = document.getElementById("TTP");
var data = JSON.parse("information");
results.innerHTML = "";
for(var obj in data){
results.innerHTML += data[obj].user+" is present +"<br />";
}
results.innerHTML = "requesting...";
}
</script>
</head>
<body>
<textarea id="TTP"></textarea>
<div id="results"></div>
<input type="button" onClick="parser()" value="Run"></input>
</body>
</html>
JSON Data
{ "user":"John", "age":22, "country":"United States" },
{ "user":"Will", "age":27, "country":"United Kingdom" },
{ "user":"Abiel", "age":19, "country":"Mexico" },
{ "user":"Rick", "age":34, "country":"Panama" },
{ "user":"Susan", "age":23, "country":"Germany" },
{ "user":"Amy", "age":43, "country":"France" },
{ "user":"Pete", "age":18, "country":"Italy" },
{ "user":"Chris", "age":25, "country":"United States" },
{ "user":"Louis", "age":31, "country":"Spain" },
{ "user":"Emily", "age":38, "country":"Uraguay" },
{ "user":"Shawn", "age":52, "country":"Chile" },
{ "user":"Greg", "age":24, "country":"Romania" }

There are a few issues in your code, the main one being your parsing of information
You're passing the literal string "information" instead of the value of the text box
The other issues are with your string concatenation as pointed out by Nick Parsons, and with the line results.innerHTML = "requesting..."; as this will just override what your for loop has set
function parser() {
var results = document.getElementById("results");
var information = document.getElementById("TTP");
var data = JSON.parse(information.value);
results.innerHTML = "";
for (var obj in data) {
results.innerHTML += data[obj].user + " is present <br/> ";
}
}
<textarea id="TTP"></textarea>
<div id="results"></div>
<input type="button" onClick="parser()" value="Run"></input>
P.S you will have to wrap your dataset in [] to denote it's an array

function parser(){
var results = document.getElementById("results");
var information = document.getElementById("TTP").value; // <-- 1
var data = JSON.parse(information); // <-- 2
results.innerHTML = "";
for(var obj in data){
results.innerHTML += data[obj].user+" is present <br>"; // <-- 3
}
//results.innerHTML = "requesting..."; // <-- 4
}
<textarea id="TTP">[{ "user":"John", "age":22, "country":"United States" },
{ "user":"Will", "age":27, "country":"United Kingdom" },
{ "user":"Abiel", "age":19, "country":"Mexico" },
{ "user":"Rick", "age":34, "country":"Panama" },
{ "user":"Susan", "age":23, "country":"Germany" },
{ "user":"Amy", "age":43, "country":"France" },
{ "user":"Pete", "age":18, "country":"Italy" },
{ "user":"Chris", "age":25, "country":"United States" },
{ "user":"Louis", "age":31, "country":"Spain" },
{ "user":"Emily", "age":38, "country":"Uraguay" },
{ "user":"Shawn", "age":52, "country":"Chile" },
{ "user":"Greg", "age":24, "country":"Romania" }]</textarea>
<div id="results"></div>
<input type="button" onClick="parser()" value="Run"></input>
Changes:
document.getElementById() gets an element, you need its value
"information" is a string, information is the variable you want to parse
" is present +"<br />" was not a correct string
The "requesting..." string overwrote the result, it is commented now
Your JSON is not a JSON, it needs surrounding []-s to become a list

Related

How to inject data from JSON to HTML

I am working on a small project to read JSON file and insert each object into a DIV in already existed HTML. So if you check the below, I need id and class from JSON file to show up under this order:
"id": external-events-list "class": fc-event fc-h-event.fc-daygrid-event.fc-daygrid-block-event.fc-event-main
The issue is, I can't get it to work to go where I want it. Please check this JS Code:
<script>
$(document).ready(function () {
$.getJSON("resources.json",
function (data) {
var employee = '';
$.each(data, function (key, value) {
//CONSTRUCTION OF ROWS HAVING
// DATA FROM JSON OBJECT
employee += '<tr>';
employee += '<td>' +
value.id + '</td>'; // THe ID is showing up - So like this it works!
employee += '<div class="fc-event-main">' + '<div class="fc-event.fc-h-event.fc-daygrid-event.fc-daygrid-block-event">' +
value.title + '</div>' + '</div>'; //But this Doesn't WORK!
});
//INSERTING ROWS INTO TABLE
$('.fc-event-main').append(employee);
});
});
</script>
And here is the HTML Code:
<body>
<div id='wrap'>
<div id='external-events'>
<div id='external-events-list'>
<div class='fc-event fc-h-event fc-daygrid-event fc-daygrid-block-event'>
<div class='fc-event-main'>Employee 1</div>
</div>
<div class='fc-event fc-h-event fc-daygrid-event fc-daygrid-block-event'>
<div class='fc-event-main'>Employee 2</div>
</div>
</div>
</body>
</html>
and the JSON code that I'm reading is like:
[
{
"id": "1",
"title": "John",
},
{
"id": "2",
"title": "Tom",
}
]
Its hard to tell what exactly you want this script to do because you're mixing table cells with div tags and a list that appends every div with a class tag. There are many little mistakes. Here's my interpretation. Take a look. Notice I've used backticks and template literals to display the data. This makes the code cleaner and easier to read.
$(document).ready(function() {
// $.getJSON("resources.json",
// function(data) {
let data = [{
"id": "1",
"title": "John",
},
{
"id": "2",
"title": "Tom",
}
]
let employee = '';
$.each(data, function(key, value) {
employee += `<div class='fc-event fc-h-event fc-daygrid-event fc-daygrid-block-event'>
<div class='fc-event-main'>Employee ${key+1}</div>
<table><tr><td>${value.id}</td>
<td><div class="fc-event-main">
<div class="fc-event.fc-h-event.fc-daygrid-event.fc-daygrid-block-event">${value.title}</div>
</div></td></tr></table>
</div>`;
});
//INSERTING ROWS INTO TABLE
$('#external-events-list').append(employee);
// });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='wrap'>
<div id='external-events'>
<div id='external-events-list'>
</div>
</div>
</div>
If you want something a little more robust and abstracted, you might find this interesting, apply to styling/classes as needed.
If working with items you might want to be adding and removing, you should work on the object then run a render function to render things, this is especially important if you're adding click events to things.
let employee = (function() {
let root, form, data = []
function init(elm, items) {
root = elm
data = items
render()
}
function cancel() {
form.find('[name="title"], [name="id"]').val('')
form.find('.add').show()
form.find('.update, .cancel').hide()
}
function add(id, title) {
data.push({
id: data.length ? parseInt(data[data.length - 1].id, 10) + 1 : 1,
title: form.find('[name="title"]').val()
})
cancel()
render()
}
function edit(item) {
form.find('[name="id"]').val(item.id)
form.find('[name="title"]').val(item.title)
form.find('.add').hide()
form.find('.update, .cancel').show()
}
function update() {
let id = parseInt(form.find('[name="id"]').val(), 10)
data.splice(data.findIndex(v => v.id === id), 1, {
id,
title: form.find('[name="title"]').val()
})
cancel()
render()
}
function remove(item) {
data.splice(data.indexOf(item), 1)
render()
}
function render() {
root.empty()
form = $(`
<form>
<input type="hidden" name="id" />
<input type="text" name="title" />
<button type="button" class="add">+</button>
<button type="button" class="update">✔️</button>
<button type="button" class="cancel">x</button>
</form>
`)
form.find('.add').click(add)
form.find('.update').hide().click(update)
form.find('.cancel').hide().click(cancel)
let list = $('<div id="events-list" />')
$.each(data, function(key, value) {
let item = $(`
<div>
<div>
Employee ${parseInt(value.id, 10)} - ${$('<span/>').text(value.title).text()}
<button class="delete">X</button> <button class="edit">Edit</button>
</div>
</div>
`)
item.find('.delete').click(() => remove(value))
item.find('.edit').click(() => edit(value))
list.append(item)
})
root.append(list)
root.append(form)
}
return {
init
}
})()
$(document).ready(function() {
// $.getJSON("resources.json", function(data) {
let data = [{
"id": "1",
"title": "John",
},
{
"id": "2",
"title": "Tom",
}
]
employee.init($('#events'), data || [])
//})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='events'></div>

access object in parsed nested JSON in Google Apps Script

I am trying to access the student tags array which has an object inside of it (student_tags:tag:"do not contact") Can someone please help me with the syntax on getting this data? I am pretty sure my syntax in retrieving this array is incorrect.
JSON Data being fetched:
{
"id":"e90c4c93-207c-49f7-89c4-eb85b3315dd5",
"created_by_user_id":"8560ed12-2858-4237-bea2-3dcab82637d3",
"date_created":"2019-08-06T22:54:59.583257+00:00",
"person_number":5973,
"first_name":"Test",
"middle_name":"James",
"last_name":"Cook",
"birth_name":null,
"email":"test#gmail.com",
"alt_email":null,
"facebook_url":null,
"linkedin_url":"https://www.linkedin.com/in/test-burns-273a5165/",
"gender":"Male",
"phone_numbers":[
{
"phone_type":"Mobile",
"number":"449288809"
},
{
"phone_type":"Home",
"number":"93938289"
}
],
"is_no_contact":false,
"is_client":false,
"student_detail":{
"onboarding_student_setting_id":"e189187a-cc91-43c6-ac44-635328b1e95a",
"student_onboarding_setting":{
"id":"e189187a-cc91-43c6-ac44-635328b1e95a",
"created_by_user_id":"562a63a2-e24e-4ff7-8358-dfb74ed6c70a",
"title":"High School On-boarding Process",
"description":"High School On-boarding Process",
"is_default":false,
"onboarding_steps":[
{
"step_id":"9cd30560-1c3c-4382-b8a2-505e78b9ce4d",
"set_tags":[
"Student Tag"
],
"set_to_status":"Potential",
"title":"Contact",
"short_title":"Contact",
"is_attachment_required":null
},
{
"step_id":"e6f90546-a516-416c-a880-9adc10358f1d",
"set_tags":[
],
"set_to_status":"Pipeline",
"title":"Program Orientation",
"short_title":"PO",
"is_attachment_required":null
},
{
"step_id":"8660df59-ddd8-4182-b6ca-c44e3de70969",
"set_tags":[
],
"set_to_status":"Confirmed",
"title":"Parental Consent",
"short_title":"Parental Consent",
"is_attachment_required":true
}
],
"is_disabled":false
},
"student_onboarding_history":[
],
"onboarding_steps_complete":null,
"onboarding_percent":null,
"graduating_student_setting_id":null,
"student_graduating_setting":null,
"student_graduating_history":[
],
"graduating_steps_complete":null,
"graduating_percent":null,
"is_active":true,
"date_deactivated":"2019-08-09T03:36:57.977584",
"deactivated_person_id":"562a63a2-e24e-4ff7-8358-dfb74ed6c70a",
"deactviated_notes":null,
"student_status":"Pipeline",
"language_group":null,
"heritage":null,
"date_ics_set":"2019-08-08T04:28:48.832170",
"ics_by_person_id":"562a63a2-e24e-4ff7-8358-dfb74ed6c70a",
"ics_status":"Active",
"ics_id":null,
"ics_start":null,
"ics_end":null,
"ics_notes":null,
"student_tags":[
{
"tag":"Do not contact",
"date_added":"2019-08-13 06:06:13.012817"
}
],
"student_source":"Other",
"date_of_birth":"2019-08-07",
"semester_number_start":null,
"semester_year_start":null,
"semester_number_end":null,
"semester_year_end":null,
"location_address":{
"line_1":"34 Adelaide Avenue",
"line_2":"",
"suburb":"east lindfield",
"postcode":"2322",
"state":"",
"country_code":"AU",
"location_description":"east lindfield, ",
"formatted_location":null,
"latitude":"-33.7691871",
"longitude":"151.1863407"
},
"emergency_first_name":"Someone",
"emergency_last_name":"",
"emergency_phone_numbers":[
],
"emergency_address":{
"line_1":"hi",
"line_2":"",
"suburb":"willoughby",
"postcode":"4154",
"state":"NSW",
"country_code":"AU",
"location_description":"willoughby, NSW",
"formatted_location":null,
"latitude":"-33.804179",
"longitude":"151.2042376"
},
"emergency_relationship":"Auntie",
"university":null,
"campus":null,
"degree_pool_id":[
],
"degree":null,
"degree_major":null,
"high_school":"School",
"high_school_complete":null,
"is_travel_required":null,
"date_alumni_set":null,
"alumni_set_by_person_id":null,
"alumni_company":null,
"alumni_job_title":null,
"alumni_city":null,
"alumni_state":null,
"alumni_country_code":null,
"alumni_notes":null,
"is_at_risk":null,
"date_at_risk_set":null,
"at_risk_by_person_id":null,
"at_risk_context":null,
"at_risk_reasons":null,
"at_risk_semester":null,
"at_risk_year":null,
"at_risk_notes":null,
"quick_notes":null,
"cv_url":null,
"public_summary":null,
"public_profile":null,
"is_graduating":null,
"graduating_by_person_id":null,
"graduating_semester":null,
"graduating_year":null,
"graduating_notes":null,
"advisor_users":[
{
"date_created":"2019-08-06T22:54:59.582970+00:00",
"is_primary":true,
"advisor_person_id":"8560ed12-2858-4237-bea2-3dcab82637d3"
}
]
},
"contact_detail":{
"company_id":null,
"contact_tags":null,
"location_address":{
"line_1":null,
"line_2":null,
"suburb":null,
"postcode":null,
"state":null,
"country_code":null,
"location_description":null,
"formatted_location":null,
"latitude":null,
"longitude":null
},
"job_title":null,
"quick_notes":null,
"is_primary":null,
"is_billing":null,
"is_student_contact":null,
"advisor_users":null
},
"current_placements":null,
"previous_placements":null
}
The function returning the JSON response:
var url = "http://api.com/v1/";
var response = UrlFetchApp.fetch(url, options);
var message = response.getContentText();
var code = response.getResponseCode();
Logger.log(message)
var tags = message["student_tags"][0]
Logger.log(tags)
In response to 'would you know how to use the key/value loop to access the same student tag value ("Do not contact")?', I'm not sure I understand the question, but the below code may be a good place to start. Let me know if I'm way off track...
var tags = message.student_detail.student_tags,
i = 0,
len = tags.length;
for (i; i < len; i++) {
var obj = tags[i];
for (a in obj) {
console.log(a, obj[a])
}
}

Filtering complex object inside nested ng-repeat

I want to filter object inside nested ng-repeat.
HTML:
<div ng-controller="MyController">
<input type="text" ng-model="selectedCityId" />
<ul>
<li ng-repeat="shop in shops">
<p ng-repeat = "locations in shop.locations | filter:search" style="display: block">
City id: {{ locations.city_id }}
<span style="padding-left: 20px; display: block;" ng-repeat="detail in locations.details | filter:item">Pin code: {{detail.pin}}</span>
</p>
</li>
</ul>
Controller:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.search = function (location) {
if ($scope.selectedCityId === undefined || $scope.selectedCityId.length === 0) {
return true;
}
if (location.city_id === parseInt($scope.selectedCityId)) {
return true;
}
};
$scope.item = function (detail) {
if ($scope.selectedCityId === undefined || $scope.selectedCityId.length === 0) {
return true;
}
if (detail.pin == parseInt($scope.selectedCityId)) {
return true;
}
};
$scope.shops =
[
{
"category_id":2,
"locations":[
{
"city_id":368,
"details": [{
"pin": 627718,
"state": 'MH'
}]
}
]
},
{
"name":"xxx",
"category_id":1,
"locations":[
{
"city_id":400,
"region_id":4,
"details": [{
"pin": 627009,
"state": 'MH'
},{
"pin": 129818,
"state": 'QA'
}]
},
]
},
];
});
Here's the fiddle:
http://jsfiddle.net/suCWn/210/
I want to use multiple filter inside ng-repeat.
Example: Whenever user enters the ID in the input box. The list should filter based on cityID or PinCode.
if user enter '129818' it should show pin code result of 129818 along with its parent cityID
Similarly, if a user enter 400, the list should filter and show cityID result with 400 along with its child pin code.
EDIT:
Update Code http://codepen.io/chiragshah_mb/pen/aZorMe?editors=1010]
First, you must not filter locations with matching details. Use something like this in the search filter:
$scope.search = function (location) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || location.city_id === id ||
location.details.some(function(d) { return d.pin === id });
};
To show details if filtered by cityID, you have to find the parent location and check if it was filtered.
$scope.item = function (detail) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || detail.pin === id || locationMatches(detail, id);
};
function locationMatches(detail, id) {
var location = locationByDetail(detail);
return location && location.city_id === id;
}
function locationByDetail(detail) {
var shops = $scope.shops;
for(var iS = 0, eS = shops.length; iS != eS; iS++) {
for(var iL = 0, eL = shops[iS].locations.length; iL != eL; iL++) {
if (shops[iS].locations[iL].details.indexOf(detail) >= 0) {
return shops[iS].locations[iL];
}
}
}
}
EDIT Another, more flexible solution would be to remove all the filters from ngRepeats and do the filtering in a method that you call on ngChange of the search text. Here is the basic structure for this approach.
myApp.controller('MyController', function($scope, $http) {
var defaultMenu = [];
$scope.currentMenu = [];
$scope.searchText = '';
$http.get(/*...*/).then(function (menu) { defaultMenu = menu; } );
$scope.onSearch = function() {
if (!$scope.searchText) {
$scope.currentMenu = defaultMenu ;
}
else {
// do your special filter logic here...
}
};
});
And the template:
<input type="text" ng-model="searchText" ng-change="onSearch()" />
<ul>
<li ng-repeat="category in currentMenu">
...
</li>
</ul>
I have updated your filters. The problem is in your search filter you are only checking for the city_id, what you should do is:
Check if the typed id is city_id
Check if typed id is a pid of a child detail of given location
Similar thing for the item filter:
Check if the typed id is a pid of the detail being filtered
Check if the typed id is a city_id of the parent location of the detail passed in
Here is a working jsFiddle. I hope this helps.
By simply modifying the JSON to include the city_id for children so you don't need to loop through it to get the parent's city_id, the solution is as easy as this:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.search = function (location) {
if (!$scope.selectedCityId)
return true;
//if user's input is contained within a city's id
if (location.city_id.toString().indexOf($scope.selectedCityId) > -1)
return true;
for (var i = 0; i < location.details.length; i++)
//if user's input is contained within a city's pin
if (location.details[i].pin.toString().indexOf($scope.selectedCityId) > -1)
return true;
};
$scope.item = function (detail) {
if (!$scope.selectedCityId)
return true;
//if user's input is contained within a city's id
if (detail.city_id.toString().indexOf($scope.selectedCityId) > -1)
return true;
//if user's input is contained within a city's pin
if (detail.pin.toString().indexOf($scope.selectedCityId) > -1)
return true;
};
Modified JSON
$scope.shops=[{"category_id":2,"locations":[{"city_id":368,"details":[{"city_id":368,"pin":627718,"state":'MH'}]}]},{"name":"xxx","category_id":1,"locations":[{"city_id":400,"region_id":4,"details":[{"city_id":400,"pin":627009,"state":'MH'},{"city_id":400,"pin":129818,"state":'QA'}]},]},];});
If directly modifying the JSON is not possible, you can modify it like this in this controller directly after this $scope.shops = ...json... statement:
for(var i=0; i<$scope.shops.length; i++)
for(var j=0, cat=$scope.shops[i]; j<cat.locations.length; j++)
for(var k=0, loc=cat.locations[j]; k<loc.details.length; k++)
loc.details[k].city_id=loc.city_id;
Working fiddle:
http://jsfiddle.net/87e314a0/
I tried to make the solution easier to understand :
index.html :
<div ng-controller="MyController">
<input type="text" ng-model="search.city_id" />
<ul>
<li ng-repeat="shop in shops">
<p ng-repeat = "locations in shop.locations | filter:search.city_id" style="display: block">
City id: {{ locations.city_id }}
<span style="padding-left: 20px; display: block;" ng-repeat="detail in locations.details | filter:item">Pin code: {{detail.pin}}</span>
</p>
</li>
</ul>
</div>
app.js :
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.shops =
[
{
"category_id":2,
"locations":[
{
"city_id":368,
"details": [{
"pin": 627718,
"state": 'MH'
}]
}
]
},
{
"name":"xxx",
"category_id":1,
"locations":[
{
"city_id":400,
"region_id":4,
"details": [{
"pin": 627009,
"state": 'MH'
},{
"pin": 129818,
"state": 'QA'
}]
},
]
},
];
});
Here's the fiddle :
mySolution

Add item to array Angular

I have a table with these fields: product, lot, input1, input2. You can clone a line, and you can add a new line.
What I want to do is that for each row you can add a new Lot created by a "number" and by "id" that user write in the input field under the Select lot. And I wanted that the script add the new Lot in the json data and the lot 's option list.
This is the function for add that I tried to do:
$scope.addLot = function() {
var inWhichProduct = row.selectedProduct;
var newArray = {
"number": row.newLot.value,
"id": row.newLot.id
};
for (var i = 0; i < $scope.items.length; i++) {
if ($scope.items[i].selectedProduct === inWhichProduct) {
$scope.items[i].selectedLot.push(newArray);
}
}
};
-->> THIS <<-- is the full code.
Can you help me?
I think your question is a little too broad to answer on Stack Overflow, but here's an attempt:
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat="lot in lots">
<td>{{ lot.id }}</td>
<td>{{ lot.name }}</td>
</tr>
</table>
<p>name:</p> <input type="text" ng-model="inputName">
<p>id:</p> <input type="text" ng-model="inputId">
<button ng-click="addLotButton(inputId, inputName)">Add</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.lots = [{
name: "test",
id: 1
},
{
name: "test2",
id: 2
}
];
$scope.addLot = function(lotId, lotName) {
var newLotObject = {
name: lotName,
id: lotId
};
$scope.lots.push(newLotObject);
};
$scope.addLotButton = function(id, name) {
$scope.addLot(id, name);
};
$scope.addLot(3, "Another test");
});
</script>
Basically this code just takes some input and adds an object to the scope for that input. The table is created using an ng-repeat of this data. It's not great code at all but it's just a quick example.
The push method adds newArray to selectedLot array. It's not working on the JSON data but on arrays. If you want to have the JSON, you can give a try to :
var myJsonString = JSON.stringify(yourArray);
It will create a JSON string based on the parameter
Maybe you should try to structure your data to make lots as properties of products.
{
products: [
{id: 1, lots: [{id:1}, {id:2}]},
{id: 2, lots: [{id:1}, {id:2}]}
]
}
To add a lot to a product :
product = products[0];
product.lots.push(newArray);
Change the fallowing:
html:
<button ng-click="addLot(row.selectedProduct.id,row.newLot.value,row.newLot.id)">Add</button>
js:
$scope.addLot = function(id,val,lotId) {
// console.log(id);
var inWhichProduct = id;
var newArray = { "value": val, "id": lotId };
//console.log($scope.items)
angular.forEach($scope.items,function(v,i){
if($scope.items[i].id == id )
{
$scope.items[i].lots.push(newArray);
console.log($scope.items[i].lots);
}
});
};
http://plnkr.co/edit/W8eche8eIEUuDBsRpLse?p=preview

How do I create copyable html code with Angular JS

I have an array of objects called sections. Each object (section in sections) has properities like name, cssclass and more. Ex:
$scope.sections = [
{ title 'first section', cssclass: 'red'},
{ title: 'second section', cssclass: 'blue'}
];
What would be the best way to output some HTML-Code in the view that any user can copy?
Let's say for example that it outputs exactly
<section class="red"> <h1> first section </h1></section>
<section class="blue"> <h1>second section</h1></section>`
and so on for looping for all the objects that the sections array may have.
Just to clarify one more time, I'd like a textarea (or something similar) where the html isn't processed but shown to the user in raw form
One can use 'pass' in $compile to do directive-processing at will and then do whatever you want with with the angularJS-generated HTML. In addition, one has to supply a unique scope based on the user's model input to the new element, which can be accomplished with $rootScope.$new(). In the example below, the model format is expected to be JSON, so that it doesn't like, explode, but if one is creating this for personal use one could allow simple JS input and use eval(), allowing the user to write a more sophisticated model.
Here it is in action: http://jsbin.com/taqoqi/1/
var module = angular.module('module', []);
module.directive('xxAngulizer', function($compile, $rootScope) {
return {
restrict: 'A',
template: '<div>TEMPLATE</div><textarea id="template" ng-model="template" ng-change="update"></textarea>' +
'<div>MODEL</div><textarea id="model" ng-model="model" ng-change="update"></textarea>' +
'<div>HTML OUTPUT</div><textarea id="output" ng-model="output"></textarea>' +
'<div id="hidden" ng-hide="true"></div>',
scope: true,
link: function($scope, elem) {
var templateElem = $(elem.find('#template'));
var modelElem = $(elem.find('#model'));
var outputElem = $(elem.find('#output'));
var hiddenElem = $(elem.find('#hidden'));
$scope.template = '<div ng-repeat="cat in cats">{{cat.name}} the famous {{cat.breed}}</div>';
$scope.model = '{ "cats": [{ "name": "Fussy", "breed": "Russian Blue" },' +
' { "name": "Juniper", "breed": "Maine Coon" },' +
' { "name": "Chives", "breed": "Domestic Shorthair" }] }';
$scope.output = '';
$scope.update = update;
var $magicScope;
function update() {
var model, template;
try {
model = JSON.parse($scope.model);
} catch (err) {
model = null;
$scope.output = 'Model is not valid JSON.';
}
if (model) {
try {
template = $($scope.template);
} catch (err) {
console.log(err);
template = null;
$scope.output = 'Template is not valid(ish) HTML.';
}
}
if (template) {
if ($magicScope) { $magicScope.$destroy(); }
$magicScope = $rootScope.$new(true);
for (var p in model) {
$magicScope[p] = model[p];
}
//$scope.$apply(function() {
$compile(hiddenElem.html(template))($magicScope);
//});
//$scope.$apply(function(){
// $scope.output = hiddenElem.html();
//});
setTimeout(function(){
$scope.output = hiddenElem.html();
$scope.$apply();
}, 500);
}
}
$scope.$watch('template', update);
$scope.$watch('model', update);
setTimeout(update, 500);
}
};
});
<!DOCTYPE html>
<html>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<body ng-app="module">
<div xx-angulizer></div>
</body>
</html>
Hope this help!

Categories

Resources