I'm using this code right now, but I'm not really liking the way it looks.
function createPageSettingsPopup(page) {
return '<div class="form-group">' +
'<label for="page-title">Title</label>' +
'<input type="text" class="form-control" id="page-title" value="' + page.title + '">' +
'</div>'
}
Is there any alternative to write the HTML in strings to make it look better?
You could use template engines. This is at the expense of elements in the page, but the code will look much cleaner and the template easier to understand as HTML. Put the template in a script tag with type set to text/template
<script type="text/template" id="tmpl">
<div class="form-group">
<label for="page-title">Title</label>
<input type="text" class="form-control" id="page-title" value="{{pageTitle}}">
</div>
</script>
And modify your function as below. Remember to cache the template.
var template = document.getElementById('tmpl').innerHTML; // cache the HTML
function createPageSettingsPopup(page) {
// Find an replace the {{pageTitle}} with page.title, and then return the HTML string.
return template.replace(new RegExp('{{pageTitle}}', 'gi'), page.title)
}
var template = document.getElementById('tmpl').innerHTML; // cache the HTML
function createPageSettingsPopup(page) {
// Find an replace the {{pageTitle}} with page.title, and then return the HTML string.
return template.replace(new RegExp('{{pageTitle}}', 'gi'), page.title)
}
console.log(
createPageSettingsPopup({title:'Hello World'})
);
<script type="text/template" id="tmpl">
<div class="form-group">
<label for="page-title">Title</label>
<input type="text" class="form-control" id="page-title" value="{{pageTitle}}">
</div>
</script>
The above is a minimal example of a template engine, but there are great ones like mustache, handlebars.js, and pug.js
Assuming ES6 you can use backticks:
return `<div>
...
</div>`;
Or have a look at react, to manipulate your DOM, they use jsx which is really nice:
const element = <h1>Hello, world!</h1>;
In case you are using jQuery, sometimes you can do things like these:
var div = $('div').addClass('form-group');
div.append($('label').attr('for', 'page-title').text('Title');
...
Depending on your problem at hand it might also make sense to have the full html structure written up-front and then just manipulate some content and styling using js. In your example:
$('div#title').show();
$('div#title').find('label.page-title').text('Title');
You can try creating a HTML utility that creates elements, add necessary properties and the returns element.
I have created a small implementation of this utility in sample. Benefit of this is you can modify this utility to work with JSON based structure to create dynamic HTML.
Sample
function createPageSettingsPopup(page) {
var divParams = {
class: 'form-group'
}
var labelParams = {
for: 'page-title'
}
var inputParams = {
type: 'text',
class: "form-control",
id: 'page-title',
value: page.title
}
var div = utils.createMyElement('div', '', divParams);
var label = utils.createMyElement('label', 'Title', labelParams)
var input = utils.createMyElement('input', '', inputParams)
div.appendChild(label);
div.appendChild(input);
document.body.appendChild(div)
}
window.addEventListener('load', function() {
createPageSettingsPopup({
title: "foo"
})
})
// This code can be exported to another file
var utils = (function() {
function createMyElement(type, htmlString, params) {
var el = document.createElement(type);
if (htmlString)
el.innerHTML = htmlString;
addProps(el, params)
return el;
}
function addProps(el, props, key) {
if (Object.keys(props).length) {
for (var k in props) {
if (typeof(props[k]) === "object") {
addProps(el, props[k], k);
} else {
if (key) {
el[key][k] = props[k]
} else {
el[k] = props[k]
}
}
}
}
}
return {
createMyElement: createMyElement
}
})()
You can also try JSON based form.
Sample
JSFiddle
window.addEventListener('load', function() {
createPageSettingsPopup({
title: "foo"
})
})
function createPageSettingsPopup(page) {
var form = utils.createForm(getFormData(page))
document.body.appendChild(form)
}
// This can be stored in JSON file or in db and then can be fetched
function getFormData(page) {
var json = {
type: "div",
params: {
class: 'form-group',
innerHTML: "",
},
children: [{
type: 'label',
params: {
for: 'page-title',
innerHTML: "Title"
},
}, {
type: 'input',
params: {
type: 'text',
class: "form-control",
id: 'page-title',
value: page.title
}
}]
}
return json
}
// This is a generic utility and can be exported to a utility file
var utils = (function() {
function JSONBasedForm(form_json) {
var el = "";
if (form_json) {
el = createMyElement(form_json.type, form_json.params);
if (form_json.children && form_json.children.length > 0) {
form_json.children.forEach(function(child) {
var c_el = JSONBasedForm(child)
c_el && el.appendChild(c_el)
})
}
}
return el;
}
function createMyElement(type, params) {
var el = document.createElement(type);
addProps(el, params)
return el;
}
function addProps(el, props, key) {
if (Object.keys(props).length) {
for (var k in props) {
if (typeof(props[k]) === "object") {
addProps(el, props[k], k);
} else {
if (key) {
el[key][k] = props[k]
} else {
el[k] = props[k]
}
}
}
}
}
return {
createForm: JSONBasedForm
}
})()
This does not look better but is another way to create elements in JavaScript
Using the document.createElement you have more programmatic control over which attributes to set
function createPageSettingsPopup(page) {
var div = document.createElement("div");
div.className="form-group";
var label = document.createElement("label");
label.htmlFor="page-title";
label.textContent="Title";
var input = document.createElement("input");
input.type="text";
input.className="form-control";
input.id="page-title";
input.value=page.title;
label.appendChild(input);
div.appendChild(label);
return div;
}
Same in jQuery:
function createPageSettingsPopup(page) {
var $div = $("<div />",{"class":"form-group"});
$div.append(
$("<label />", {"htmlFor":"page-title").text("Title").append(
$("<input/>", { "type":"text","class":"form-control","id":"page-title"}).val(page.title)
)
);
return $div;
}
Related
I am trying to create an sdk in javscript/jquery for creating templates based on user input, such as the type of templates - profile template, dialog template. These templates require data from an ajax call for their creation.
User Input should include some config param and type of templates.
Since I don't have much experience creating sdk's, I am trying to create a scalable and flexible sdk which can adopt some more functionalities and properties in future.
I am stuck on the problem that what is the basic and best way to create an javascript/jquery sdk?
var dialogTemplate , var = template2 I have added sample templates. The requirement is when user passes template/templates name in tmpConfig.config.type create that particular template/templates by fetching their data simultaneously for each template/templates.Suppose, when call 'dialog template' create dialog template. when call 'dialog template' and 'template2' create both and append it. These template name can be send in array in config.
Below is what I have tried:-
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="mySDK.js"></script>
</head>
<body>
// container for templates
<div id="tmpBox"></div>
</body>
<script type="text/javascript">
const tmpConfig = {
config: {
type: ['dialog','template2',...,...,....]
},
boxId: '#tmpBox'
};
var mySDK= new tmpSDK(tmpConfig );
mySDK.createtemplate(); // create template
</script>
</html>
mySDK.js
function tmpSDK(confg){
// implementation of sdk
this.config = confg;
}
tmpSDK.prototype.createtemplate= function(){
var idsToAppendTemplate = this.config.boxId;
var templateTypes = this.config.type;
// checking number of templates to create
for(var i=0 ; i < templateTypes.length; i++){
if(templateTypes === 'dialog'){
createDialog(idsToAppendTemplate )
}else if(templateTypes === 'template2'){
createTemplate2 (idsToAppendTemplate )
}
}
}
function getData(ajaxConfig){
$.ajax(){
return data;
}
}
// different templates html defined below:-
var dialogTemplate = function(data){
// play with data
var html = '<div class='dialog-template'>MY Dialog Template</div>';
return html;
}
var template2 = function(data){
// play with data
var html = '<div class='template2'>MY Template2</div>';
return html;
}
tmpSDK.prototype.createDialog = function(id){
var ajaxConfig = {
'url' : 'http://dialog endponts/',
....
}
var data = getData(ajaxConfig);
$(id).append(dialogTemplate(data)); // var dialogTemplate
}
tmpSDK.prototype.createTemplate2 = function(id){
var ajaxConfig = {
'url' : 'http://template2endponts/',
....
}
var data = getData(ajaxConfig);
$(id).append(template2(data) ); //// var template2
}
Please, consider to create your sdk as jQuery module with Class using.
(function ( $ ) {
$.fn.mySdk = function(options) {
const element = $(this);
const sdk = new MySdk(options, element);
element.data('plugin-my-sdk', sdk);
return $(this);
};
$.fn.getMySdk = function() {
const element = $(this);
return element.data('plugin-my-sdk');
};
class MySdk {
constructor(options, element) {
this.element = element;
this.settings = $.extend({
type: 'dialog',
}, options );
this.fetchTemplate().done(this.applyTemplate.bind(this));
}
fetchTemplate() {
return $.post({
url: `${document.location.origin}/your-endpoint-for-getting-template`,
data: {
'id': this.element.attr('id'),
'type': this.settings.type
}
});
}
applyTemplate(template) {
this.element.html(template);
}
apiMethod() {
const yourElement = this.element;
const yourElementId = this.element.attr('id');
const yourType = this.settings.type;
}
}
}( jQuery ));
// This snippet - is example of using your sdk
jQuery(function ($) {
const element = $('#tmpBox');
element.mySdk({
type: 'dialog'
});
const sdk = element.getMySdk();
sdk.apiMethod();
});
What this snippet do?
Wrap jQuery function for creating a not global scope and for avoiding jQuery conflict with $ function name
Uses MySdk class for the element.
This works for the case when there is only one jquery element in collection taking by the selector. In this case - const element = $('#tmpBox'); is taking only one element.
This snippet
this.settings = this.settings = $.extend({
type: 'dialog',
}, options );
merges default options with your options. If there is no option in your options object - then default option will be used
If you need to use jquery collection
For example, your sdk element is $('.tmpBox') where is there are more than 1 element - please, consider to use in mySdk each function for init every element.
const elements = $(this);
element.each(function(){
// init for every element;
})
Am struggling hard to bind an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>
I'm using Firebase-util's intersection function to find all the comments for a given link. This seems to work fine the first time I call the join, but it doesn't seem to properly notify my value callback when I remove the contents of the database and replace them again. Shouldn't the references keep working as long as the resource path remains the same?
Run this example. When you click the button, it erases and recreates the data. As you can see, the comment list is not repopulated after the data gets recreated.
<link rel="import" href="https://www.polymer-project.org/components/polymer/polymer.html">
<script src="http://cdn.firebase.com/v0/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebase-util/0.1.0/firebase-util.min.js"></script>
<polymer-element name="my-element">
<template>
<h1>Test of Firebase-util.intersection</h1>
<div>
<button on-click={{initializeFirebase}}>Reset data</button>
</div>
<ul>
<template repeat="{{rootComment in comments}}">
<li>{{rootComment.comment.content}}
<ul>
<template repeat="{{subComment in rootComment.children}}">
<li>{{subComment.comment.content}}
<ul>
<template repeat="{{subSubComment in subComment.children}}">
<li>{{subSubComment.comment.content}}</li>
</template>
</ul>
</li>
</template>
</ul>
</li>
</template>
</ul>
</template>
<script>
Polymer('my-element', {
ready: function() {
var sanitizeUrl = function(url) {
return encodeURIComponent(url).replace(/\./g, '%ZZ');
};
var baseUrl = "https://nested-comments-test.firebaseio.com";
var linkUrl = baseUrl +
'/links/' +
sanitizeUrl(document.URL) +
'/comments';
var commentsUrl = baseUrl + '/comments';
var root = new Firebase(baseUrl);
this.initializeFirebase = function() {
function addLink(url, callback) {
var key = sanitizeUrl(url),
newLink = {
url: url,
createdAt: Firebase.ServerValue.TIMESTAMP
};
root.child('/links/' + key).update(newLink);
callback(key);
}
function addComment(attributes, callback) {
return root.child('/comments').push(attributes, callback);
}
function onCommentAdded(childSnapshot) {
var newCommentId = childSnapshot.name(),
attributes = {},
link = childSnapshot.val().link,
url = '/links/' + link + '/comments';
attributes[newCommentId] = true;
root.child(url).update(attributes);
}
root.remove(function() {
root.child('/comments').on('child_added', onCommentAdded);
addLink(document.URL, function(link) {
var attributes = {
link: link,
content: "This is the first comment."
},
firstCommentId, secondCommentId;
firstCommentId = addComment(attributes).name();
attributes = {
link: link,
content: "This is a reply to the first.",
replyToCommentId: firstCommentId
};
secondCommentId = addComment(attributes).name();
attributes = {
link: link,
content: "This is a reply to the second.",
replyToCommentId: secondCommentId
};
addComment(attributes);
attributes = {
link: link,
content: "This is another reply to the first.",
replyToCommentId: firstCommentId
};
addComment(attributes);
});
});
};
this.initializeFirebase();
var findChildrenForComment = function(snapshot, parentCommentId) {
var returnVal = [];
snapshot.forEach(function(snap) {
var comment = snap.val(),
commentId = snap.name();
if (comment.replyToCommentId === parentCommentId) {
var children = findChildrenForComment(snapshot, commentId);
var obj = {
commentId: commentId,
comment: comment,
parentId: parentCommentId
};
if (children.length) {
obj.children = children;
}
returnVal.push(obj);
}
});
return returnVal;
};
this.ref = Firebase.util.intersection(
new Firebase(linkUrl),
new Firebase(commentsUrl)
);
this.comments = {};
var that = this;
this.ref.on('value', function(snapshot) {
that.comments = findChildrenForComment(snapshot);
});
}
});
</script>
</polymer-element>
<my-element></my-element>
Apparently deleting a path entirely causes all callbacks on it to be canceled. The workaround for this behavior is to remove children one at a time rather than deleting their parent path.
I am having a problem with the dynamic creation of a Form. I have a directive that gets set against a form element. It uses Jquery to get the element by id. However it seems that it has not yet been added to the DOM.
<form class="form-horizontal">
<div class="control-group" ng-repeat="field in viewModel.fields">
<label class="control-label">{{field.label}}</label>
<div class="controls" ng-switch="field.type">
<input ng-switch-when="text" type="text" id="{{field.label}}" ng-model="field.data" validator="viewModel.validator" ruleSetName="personFirstNameRules"/>
<span ng-switch-when="text" validation-Message-For="{{field.label}}"></span>
</div>
</div>
<button ng-click="testID()">Submit</button>
</form>
If I hard code the ID attribute for the text field and on the span element validation-Message-For then their is no issue.The area where i am getting undefined is
var errorElementController = angular.element(errorElement).controller('ngModel');
var validatorsController = angular.element(errorElement).controller('validator');
The full directive is here
(function (angular, $) {
angular.module('directivesModule')
.directive('validationMessageFor', [function () {
return {
link: function (scope, element, attributes) {
var errorElementId = attributes.validationMessageFor;
if (!errorElementId) {
return;
}
var areCustomErrorsWatched = false;
var watchRuleChange = function (validationInfo, rule) {
scope.$watch(function () {
return validationInfo.validator.ruleSetHasErrors(validationInfo.ruleSetName, rule.errorCode);
}, showErrorInfoIfNeeded);
};
var watchCustomErrors = function (validationInfo) {
if (!areCustomErrorsWatched && validationInfo && validationInfo.validator) {
areCustomErrorsWatched = true;
var validator = validationInfo.validator;
var rules = validator.validationRules[validationInfo.ruleSetName];
for (var i = 0; i < rules.length; i++) {
watchRuleChange(validationInfo, rules[i]);
}
}
};
//alert(errorElementId);
// get element for which we are showing error information by id
var errorElement = $("#" + errorElementId);
console.log(angular.element(errorElement));
var errorElementController = angular.element(errorElement).controller('ngModel');
var validatorsController = angular.element(errorElement).controller('validator');
console.log(errorElementController);
console.log(validatorsController);
var getValidationInfo = function () {
return validatorsController && validatorsController.validationInfoIsDefined() ? validatorsController.validationInfo : null;
};
var validationChanged = false;
var subscribeToValidationChanged = function () {
if (validatorsController.validationInfoIsDefined()) {
validatorsController.validationInfo.validator.watchValidationChanged(function () {
validationChanged = true;
showErrorInfoIfNeeded();
});
// setup a watch on rule errors if it's not already set
watchCustomErrors(validatorsController.validationInfo);
}
};
var getErrorMessage = function (value) {
var validationInfo = getValidationInfo();
if (!validationInfo) {
return '';
}
var errorMessage = "";
var errors = validationInfo.validator.errors[validationInfo.ruleSetName];
var rules = validationInfo.validator.validationRules[validationInfo.ruleSetName];
for (var errorCode in errors) {
if (errors[errorCode]) {
var errorCodeRule = _.findWhere(rules, { errorCode: errorCode });
if (errorCodeRule) {
errorMessage += errorCodeRule.validate(value).errorMessage;
break;
}
}
}
return errorMessage;
};
var showErrorInfoIfNeeded = function () {
var validationInfo = getValidationInfo();
if (!validationInfo) {
return;
}
var needsAttention = validatorsController.ruleSetHasErrors() && (errorElementController && errorElementController.$dirty || validationChanged);
if (needsAttention) {
// compose and show error message
var errorMessage = getErrorMessage(element.val());
// set and show error message
element.text(errorMessage);
element.show();
} else {
element.hide();
}
};
subscribeToValidationChanged();
if (errorElementController)
{
scope.$watch(function () { return errorElementController.$dirty; }, showErrorInfoIfNeeded);
}
scope.$watch(function () { return validatorsController.validationInfoIsDefined(); }, subscribeToValidationChanged());
}
};
}]);})
(angular, $);
The error on the console is
TypeError: Cannot read property 'validationInfoIsDefined' of undefined
at subscribeToValidationChanged (http://localhost/trax/app/Directives/validationMessage.js:50:52)
at link (http://localhost/trax/app/Directives/validationMessage.js:103:24)
at nodeLinkFn (https://code.angularjs.org/1.2.13/angular.js:6271:13)
at compositeLinkFn (https://code.angularjs.org/1.2.13/angular.js:5682:15)
at publicLinkFn (https://code.angularjs.org/1.2.13/angular.js:5587:30)
at boundTranscludeFn (https://code.angularjs.org/1.2.13/angular.js:5701:21)
at Object.controllersBoundTransclude [as transclude] (https://code.angularjs.org/1.2.13/angular.js:6292:18)
at https://code.angularjs.org/1.2.13/angular.js:20073:32
at Array.forEach (native)
at forEach (https://code.angularjs.org/1.2.13/angular.js:304:11) <span ng-switch-when="text" validation-message-for="{{field.label}}" class="ng-scope">
you are writing Directive name as camel case when you are define. in this case angular read this directive as - based values
so validation-Message-For should be validation-message-for in your Html code
<span ng-switch-when="text" validation-message-for="{{field.label}}"></span>
and change the input id attribute value assigning type:
remove the {{}} from id attribute
<input ng-switch-when="text" type="text" id="field.label" ng-model="field.data" validator="viewModel.validator" ruleSetName="personFirstNameRules"/>
update
problem with ng-switch when. in your Plunker the input tags are not rendering as input field.
Be aware that the attribute values to match against cannot be expressions.
They are interpreted as literal string values to match against. For example,
ng-switch-when="someVal" will match against the string "someVal" not against the
value of the expression $scope.someVal.
refer this Question. StackOverflow Question
Updated Plunker
I want to create a Json object which has an array through javascript when a function is been called. (for example "list()"). And the function should return a json object for the following.
{
"config": [
{
"name":"steve",
"id":"123"
},
{
"name":"adam",
"id":"124"
},
{
"name":"eve",
"id":"125"
}
]
}
Thank you ...
i know that "google the question" answers are not appreciated here but seriously
how hard is it to type "javascript json" into google? and follow the very first link? here: http://www.json.org/js.html ?
Is this what you looking for
var yourArray = [
{
"name":"steve",
"id":"123"
},
{
"name":"adam",
"id":"124"
},
{
"name":"eve",
"id":"125"
}
];
JSON lib
var myJsonString = JSON.stringify(yourArray);
JQuery json
var encoded = $.toJSON( yourArray );
Json is simply the string representation for the object. The whole point of Json is that the syntax itself is valid javascript which can be parsed as an object.
It's hard to understand what you're asking here. If you just want to know how to work with the object from code you can just do something like this:
var myObj = {};
myObj.config = [];
myObj.config[0] = {};
myObj.config[0].name = "steve";
myObj.config[0].id = "123";
myObj.config[1] = {};
myObj.config[1].name = "adam";
myObj.config[1].id = "124";
myObj.config[2] = {};
myObj.config[2].name = "eve";
myObj.config[2].id = "125";
This is exactly equivalent to this:
var myObj = {
"config": [
{
"name":"steve",
"id":"123"
},
{
"name":"adam",
"id":"124"
},
{
"name":"eve",
"id":"125"
}
]
};
I have done complete bin to parse json object from array json string and shows on html format using jQuery.
HTML:
<div class="jsonobj">
</div>
<br/>
<input type="button" value="Run" id="btnrun"/>
<input type="button" value="Reset" id="btnreset"/>
CSS:
.jsonobj{
background:#ddd;
}
.jsonobj .key{
display:inline-block;
clear:both;
color:#993322;
}
.jsonobj .val{
color:#336622;
display:inline-block;
margin-left:7px;
}
input[type=button]{
border:1px solid #333;
}
input[type=button]:hover{
background:#eee;
}
JQuery:
function list(a) {
if (a == null || typeof(a) == "undefined") return false;
return JSON.parse(a);
}
$(function() {
$("#btnrun").click(function() {
var jsonarr = '{"config": [{ "name":"steve", "id":"123"}, { "name":"adam", "id":"124"},{"name":"eve","id":"125"}]}';
//Convert into JSON Object
var jsonObject = list(jsonarr);
var i = 0,
html = '';
$.each(jsonObject.config, function(k, val) {
html += "<div class='key'>Name:</div><div class='val'>" + val.name + "</div>";
html += "<br/><div class='key'>Id:</div><div class='val'>" + val.id + "</div><br/>";
});
if (html != '') {
$(".jsonobj").css({
'padding': '5px',
'border': '1px solid #222'
});
$(".jsonobj").html(html);
}
});
$("#btnreset").click(function() {
$(".jsonobj").css({
'padding': '0px',
'border': '0px'
});
$(".jsonobj").html("");
});
//Trigger Run on ready
$("#btnrun").trigger('click');
});
TRY it on http://codebins.com/bin/4ldqpai