I've the code below written in JavaScript to add a new option to the select list from the opener window:
function updateSelectList()
{
var field = opener.document.objectdata.ticketPersonId;
if (true && opener && field)
{
var val = document.createElement('option');
var title = document.objectdata.titleId.options[document.objectdata.titleId.selectedIndex].text;
val.text = title + ' ' + document.objectdata.firstName.value + ' ' + document.objectdata.lastName.value + ':' + document.objectdata.username.value;
val.value = null;
val.selected = true;
field.add(val, null);
}
}
works all fine in Firefox, Google Chrome etc but not IE 6 :-(
please advise how I can make this work in IE 6 aswell.
Here's my snippet:
if (oldopt!=null || !horus.brokenDOM)
select.add(newopt, oldopt);
else
newopt=options[options.length]=new Option(newopt.text, newopt.value, false, false);
The definition of horus.brokenDOM is left to the reader :)
IIRC, I had some difficulty with using pre-defined Option objects (generally pulled out of another selectbox) in this context with IE, hence the in-place object creation.
function updateSelectList()
{
var field = opener.<%= updatelist %>;
if (<%= called %> && opener && field)
{
var val = opener.document.createElement('option');
var title = document.objectdata.titleId.options[document.objectdata.titleId.selectedIndex].text;
val.text = title + ' ' + document.objectdata.firstName.value + ' ' + document.objectdata.lastName.value + ':' + document.objectdata.username.value;
val.value = <%= thePerson != null ? thePerson.getId() : null %>;
val.selected = true;
try
{
field.add(val, null);
}
catch(error)
{
field.add(val, 0);
}
}
}
this seams to work. What a mission!
Related
I am new to StackOverflow and very much a beginner at Javascript so I apologize if there is an obvious issue with either the code or my post. I'm not necessarily trying to do this in the best or prettiest way at the moment, just get this project working before my internship ends. I have been working on making this https://github.com/commonpike/add-to-calendar-buttons add to calendar work with internet explorer which is not compatible with Encode:URI or the HTML "Download" attribute.
With the help comments on the project and other fixes to similar problems that I've seen I THOUGHT that I could add this code in the appropriate places and get things working. The calendar function is already part of the code but I included it because it is affected.
var href2 = (
'BEGIN:VCALENDAR',
'VERSION:2.0',
'BEGIN:VEVENT',
'URL:' + document.URL,
'DTSTART:' + (startTime || ''),
'DTEND:' + (endTime || ''),
'SUMMARY:' + (event.title || ''),
'DESCRIPTION:' + (event.description || ''),
'LOCATION:' + (event.address || ''),
'UID:' + (event.id || '') + '-' + document.URL,
'END:VEVENT',
'END:VCALENDAR');
if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
return '<a class="' + eClass + '" href="javascript:msDownloadCalendar(\'' +
href2 + '\')">' + calendarName + '</a>';
} else {
return '<a class="' + eClass + '" download="' + CONFIG.texts.download + '" href="' +
href + '">' + calendarName + '</a>';
}
},
exports.msDownloadCalendar = function(url) {
if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
var blob = new Blob([href2], {
type: 'text/calendar;charset=utf-8'
});
window.navigator.msSaveOrOpenBlob(blob, 'download.ics');
}
};
exports.addToCalendar = function(params) {
if (params instanceof HTMLElement) {
//console.log('HTMLElement');
return parseCalendar(params);
}
if (params instanceof NodeList) {
//console.log('NodeList');
var success = (params.length > 0);
Array.prototype.forEach.call(params, function(node) {
success = success && addToCalendar(node);
});
return success;
}
sanitizeParams(params);
if (!validParams(params)) {
console.log('Event details missing.');
return;
}
return generateMarkup(
generateCalendars(params.data),
params.options.class,
params.options.id
);
};
This does not however fix the problem. While it has no effect on the functionality in other browsers it totally breaks it in IE as only the headers show up while the console says the function 'addtocalendar' is undefined. 'Addtocalender' only logs as undefined in IE so I have to assume something that is being brought into play by
if ((navigator.userAgent.indexOf("MSIE") != -1 ) || (!!document.documentMode == true ))
is the culprit.
Thank you so so much to anyone in the community who can give me some input and help me get this up and running. I've pushed my head against the wall about at much as I can with my current skill set, and have learned a lot, but fear I have reached my my current limit.
I apologize up front for the possible lack of clarity for this question, but I'm new to Angular.js and my knowledge of it is still slightly hazy. I have done the Angular.js tutorial and googled for answers, but I haven't found any.
I have multiple select/option html elements, not inside a form element, and I'm populating them using AJAX. Each form field is populated by values from a different SharePoint list. I'm wondering if there is a way to implement this using Angular.js?
I would like to consider building this using Angular because I like some of it features such as data-binding, routing, and organizing code by components. But I can't quite grasp how I could implement it in this situation while coding using the DRY principle.
Currently, I have a single AJAX.js file and I have a Javascript file that contains an array of the different endpoints I need to connect to along with specific query parameters. When my page loads, I loop through the arrays and for each element, I call the GET method and pass it the end-point details.
The code then goes on to find the corresponding select element on the page and appends the option element returned by the ajax call.
I'm new to Angular, but from what I understand, I could create a custom component for each select element. I would place the component on the page and all the select and options that are associated with that component would appear there. The examples I've seen demonstrated, associate the ajax call with the code for the component. I'm thinking that I could use a service and have each component dependent on that service and the component would pass it's specific query details to the service's ajax call.
My current code - Program flow: main -> data retrieval -> object creation | main -> form build.
Called from index.html - creates the multiple query strings that are passed to ajax calls - ajax calls are once for each query string - the very last function in the file is a call to another function to build the form elements.
var snbApp = window.snbApp || {};
snbApp.main = (function () {
var main = {};
main.loadCount = 0;
main.init = function () {
function buildSelectOptions(){
//***
//Build select options from multiple SharePoint lists
//***
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
for(var i = 0; i < listsArray.length; i++){
var listItem = listsArray[i];
var qryStrng = listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
var listDetails = {
listName: listItem.list,
listObj: listItem,
url: "http://myEnv/_vti_bin/listdata.svc/" + listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
};
var clientContext = new SP.ClientContext.get_current();
clientContext.executeQueryAsync(snbApp.dataretriever.letsBuild(listDetails), _onQueryFailed);
}
//***
//Build select option from other API endpoint
//***
var listDetails = {
listName:"SNB_SecondaryActivityCodes",
url: "http://myEnv/requests/odata/v1/Sites?$filter=(IsMajor eq true or IsMinor eq true) and IsActive eq true and IsPending eq false and CodePc ne null and IsSpecialPurpose eq false&$orderby=CodePc"
};
snbApp.dataretriever.letsBuild(listDetails);
}
buildSelectOptions();
//***
//Add delay to populate fields to ensure all data retrieved from AJAX calls
//***
var myObj = setTimeout(delayFieldPopulate,5000);
function delayFieldPopulate(){
var optObj = snbApp.optionsobj.getAllOptions();
var osType = $("input[name=os_platform]:checked").val();
snbApp.formmanager.buildForm(osType, optObj);
}
};
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return main
})();
AJAX calls here - called from main/previous file:
var snbApp = window.snbApp || {};
snbApp.dataretriever = (function () {
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
function getListData(listItem) {
var eventType = event.type;
var baseURL = listItem.url;
$.ajax({
url: baseURL,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
}
})
.done(function(results){
snbApp.objectbuilderutility.buildObjectFields(results, listItem);
})
.fail(function(xhr, status, errorThrown){
//console.log("Error:" + errorThrown + ": " + myListName);
});
}
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return{
letsBuild:function(item) {
getListData(item);
}
};
})();
Builds a item name object - called from recursive AJAX calls / previous file
var snbApp = window.snbApp || {};
snbApp.objectbuilderutility = (function () {
function formatItemCode(itemCode, eventType){
if(eventType !== 'change'){ //for load event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(0,3);
}
}else{ //for change event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(3);
}
}
}
return{
buildObjectFields: function(returnedObj, listItem){ //results:returnedObj, prevItem:listItem
//***
//For SharePoint list data
//***
if (listItem.listName !== "SNB_SecondaryActivityCodes") {
var theList = listItem.listName;
var firstQueryParam = listItem.listObj.codeDigits;
var secondQueryParam = listItem.listObj.codeDescription;
var returnedItems = returnedObj.d.results;
var bigStringOptions = "";
//regex to search for SecondaryFunctionCodes in list names
var pattern = /SecondaryFunctionCodes/;
var isSecFunction = pattern.test(theList);
if(isSecFunction){
bigStringOptions = "<option value='0' selected>Not Applicable</option>";
}else{
bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
}
$.each(returnedItems, function (index, item) {
var first = "";
var second = "";
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key != "__metadata") {
if (key == firstQueryParam) {
first = item[key];
}
if (key == secondQueryParam) {
second = item[key];
}
}
}
}
bigStringOptions += "<option value=" + first + " data-code=" + first + ">" + second + "</option>";
});
var str = theList.toLowerCase();
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
//***
//For other API
//***
} else {
var theList = listItem.listName;
var bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
var returnedItems = returnedObj.value;
for(var i = 0; i < returnedItems.length; i++){
var item = returnedItems[i];
//***
//change event type means the user selected a field
//***
if(listItem.eventType === "change"){
var siteCodeChange = item.SiteCodePc;
if (typeof siteCodeChange === "string" & siteCodeChange != "null") {
siteCodeChange = siteCodeChange < 6 ? siteCodeChange : siteCodeChange.slice(3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeChange + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeChange + ") " + item.Name + "</option>";
snbApp.formmanager.buildSelectSiteLocations(bigStringOptions);
//***
//load event which means this happens when the page is loaded
//***
}else{
var siteCodeLoad = item.SiteCodePc;
if (typeof siteCodeLoad === "string" & siteCodeLoad != "null") {
var siteCodeLoad = siteCodeLoad.length < 4 ? siteCodeLoad : siteCodeLoad.slice(0, 3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeLoad + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeLoad + ") " + item.Name + "</option>";
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
}
}
}
}
};
})();
Form management - called from previous file, gets all select elements on page and appends items from the object in previous file to each select element.
var snbApp = window.snbApp || {};
//Direct interface to the form on the page
snbApp.formmanager = (function(){
var form = {};
form.content_holder = document.getElementById("content_holder");
form.sec_act_codes = document.getElementById("snb_secondary_activity_codes");
form.prim_func_codes = document.getElementById("snb_primary_function_codes");
form.sec_func_codes = document.getElementById("snb_secondary_function_codes");
form.sec_func_nums = document.getElementById("snb_secondary_function_numbers");
form.host_options = document.getElementById("snb_host_options");
form.site_locs_div = document.getElementById("site_locations_div");
form.site_locs = document.getElementById("snb_site_locations");
form.dc_or_off_prem_div = document.getElementById("dc_or_off_premise_div");
form.dc_off_prem_codes = document.getElementById("snb_dc_offpremise_codes");
var snb_secondary_activity_codes = "";
var snb_primary_function_codes = "";
var snb_secondary_function_codes = "";
var snb_secondary_function_numbers = "";
var snb_host_options = "";
var snb_site_locations = "";
var snb_dc_op = "";
//builds the server location hosting options selection
function buildLocationTypeSelector() {
var locationOptionsString = "<option value='0' disabled selected>Select Option</option>";
for (var i = 0; i < locationOptions.length; i++) {
var location = locationOptions[i];
locationOptionsString += "<option value=" + location.hostLocale + " data-code=" + location.code + ">" + location.hostLocale + "</option>";
}
$("#snb_host_options").append(locationOptionsString);
}
function buildSiteLocations(bigString){
if(bigString === undefined){
var siteLocs = document.getElementById("snb_site_locations");
var newOption = document.createElement("option");
newOption.setAttribute("value", 0);
newOption.setAttribute("disabled","disabled");
newOption.setAttribute("checked","checked");
var newText = document.createTextNode("Select Option");
newOption.appendChild(newText);
siteLocs.appendChild(newOption);
} else{
var siteLocs = document.getElementById("snb_site_locations");
siteLocs.innerHTML = bigString;
}
}
return {
form:form,
buildSelectSiteLocations: function(bigString){
buildSiteLocations(bigString);
},
buildForm: function (osType, optObj) {
buildLocationTypeSelector();
buildSecondaryFunctionNumberSelector();
buildSiteLocations();
if(osType === 'windows'){
$("#snb_secondary_activity_codes").append(optObj.windows.secondary_activity);
$("#snb_primary_function_codes").append(optObj.windows.primary_function);
$("#snb_secondary_function_codes").append(optObj.windows.secondary_function);
$("#snb_site_locations").append(optObj.windows.site_location);
$("#snb_dc_offpremise_codes").append(optObj.windows.dc_offpremise);
}else{
$("#snb_secondary_activity_codes").append(optObj.unix.secondary_activity);
$("#snb_primary_function_codes").append(optObj.unix.primary_function);
$("#snb_secondary_function_codes").append(optObj.unix.secondary_function);
$("#snb_site_locations").append(optObj.unix.site_location);
$("#snb_dc_offpremise_codes").append(optObj.unix.dc_offpremise);
}
}
};
})();
Thanks in advance.
I admit not being so great with JavaScript.
I've been tasked to build a utility that will run a check to see if a campaign date is going to expire in 2 weeks or less and add a class if it's going to.
The date is coming from a service and it's built (datatables map) as follows.
The data is coming back undefined but that's a different issue.
Any feedback would be greatly appreciated because I don't seem to be having any luck whatsoever.
Initially I had a date object in there but wasn't sure it was necessary.
/*HTML Rendered Out for that table cell (there are multiple but this is how it
comes out*/
<td class=" campaign_start_date small-screen small-screen-2-col">06/14/2017 -
<div class="campaign-end-date">06/29/2017</div></td>
JS
//Datatables Code & modified for our project
{title:ax.L(114), class:'campaign_start_date small-screen small-screen-2-col', data:function(row, type, val, meta) {
var campaignEndDate = ax.Utils.deNull(row.campaign_end_date, '');
campaignEndDate = ax.Utils.RFCFormat(campaignEndDate, { excludeTime: true });
var campaignStartDate = ax.Utils.deNull(row.campaign_start_date, '');
campaignStartDate = ax.Utils.RFCFormat(campaignStartDate, { excludeTime: true });
var campaignDateString;
if (campaignEndDate && campaignStartDate ) {
campaignDateString = campaignStartDate + ' - ' + '<div class="campaign-end-date">' + ax.Utils.campaignEndDateAlert(campaignEndDate) + '</div>';
} else {
if (!campaignEndDate && campaignStartDate) {
campaignDateString = campaignStartDate + ' - ? ';
}
else if (!campaignStartDate && campaignEndDate) {
campaignDateString = ' ? - ' + campaignEndDate;
}
else {
campaignDateString = ' ';
}
}
return campaignDateString
//My attempt at doing this from the Utility file - the code that i'm having no luck with.
publicMethods.campaignEndDateAlert = function (data) {
var campaignDateEnd = data.campaign_end_date;
var $orderTable = $('#order-table');
var $campaignDate = $orderTable.find('.campaign-end-date')
if (campaignDateEnd <= campaignDateEnd + 86400000) {
$campaignDate.addClass('green');
}
}
I am trying to download an excel file on onclick event. It allow me to download excel file in chrome but not in Firefox. Not sure what is the issue. I am getting below error.
ReferenceError: event is not defined
Below is my javascript function
function hyperlinkFn(){
var htmlTbl="";
var htmlTbl1="";
var string = event.target.parentElement.name;
var tempString=[];
var temp= new Array();
for(var i=0;i<string.length;i++){
if(string[i]=="|"){
temp.push(tempString);
tempString=[];
}else{
tempString+=string[i];
}
}
userStoryModalRelease = temp[0];
userStoryModalPID = temp[1];
userStoryModalPrjName = encodeURIComponent(temp[2]);
userStoryModalTeam = encodeURIComponent(temp[3]);
userStoryAltId=encodeURIComponent(temp[4]);
userStoryModalStatus = temp[5];
userStoryModalTeam = userStoryModalTeam.replace(", ", ",");
var uri="getUserStoryDetails.htm?release=" + userStoryModalRelease + "&projectId=" + userStoryModalPID + "&projectName=" + userStoryModalPrjName +
"&team=" + userStoryModalTeam + "&alternateId=" + userStoryAltId + "&view=" + storyView;
var encode = encodeURI(uri);
window.location = encode;
}
HTML code where I am calling this function in the datatable
{
title : "Total Points",
data : function(data, type, row, meta) {
return data.totalSum+'<a name="'+ data.releaseNum +'|'+ data.projectId +'|'+ data.projectName +'|'+ data.team + '|'+ data.altId + '|total|'+'" onclick="hyperlinkFn()">'
+ '<i class="fa fa-file-excel-o font-size-15 " title="Click here to export details " aria-hidden="true"></i></a>';
},
className : "center storypoint yellow_fill pos-rel"
} ],
Change your click binding like below so that event will work:
$(document).on('click', '.classname', function(event){
var htmlTbl="";
var htmlTbl1="";
var string = event.target.parentElement.name;
var tempString=[];
var temp= new Array();
for(var i=0;i<string.length;i++){
if(string[i]=="|"){
temp.push(tempString);
tempString=[];
}else{
tempString+=string[i];
}
}
userStoryModalRelease = temp[0];
userStoryModalPID = temp[1];
userStoryModalPrjName = encodeURIComponent(temp[2]);
userStoryModalTeam = encodeURIComponent(temp[3]);
userStoryAltId=encodeURIComponent(temp[4]);
userStoryModalStatus = temp[5];
userStoryModalTeam = userStoryModalTeam.replace(", ", ",");
var uri="getUserStoryDetails.htm?release=" + userStoryModalRelease + "&projectId=" + userStoryModalPID + "&projectName=" + userStoryModalPrjName +
"&team=" + userStoryModalTeam + "&alternateId=" + userStoryAltId + "&view=" + storyView;
var encode = encodeURI(uri);
window.location = encode;
})
Note: remove onclick event from hyperlink and add class on hyperlink and replace that classname with .classname
Looks like this has already been covered here:
ReferenceError: event is not defined error in Firefox
WebKit follows IE's old behavior of using a global symbol for "event", but
Firefox doesn't. When you're using jQuery, that library normalizes the
behavior and ensures that your event handlers are passed the event
parameter.
function hyperlinkFn(){ needs to become function hyperlinkFn( event ){
Okay, that title will sound a bit crazy. I have an object, which I build from a bunch of inputs (from the user). I set them according to their value received, but sometimes they are not set at all, which makes them null. What I really want to do, it make an item generator for WoW. The items can have multiple attributes, which all look the same to the user. Here is my example:
+3 Agility
+5 Stamina
+10 Dodge
In theory, that should just grab my object's property name and key value, then output it in the same fashion. However, how do I setup that if-statement?
Here is what my current if-statement MADNESS looks like:
if(property == "agility") {
text = "+" + text + " Agility";
}
if(property == "stamina") {
text = "+" + text + " Stamina";
}
if(property == "dodge") {
text = "+" + text + " Dodge";
}
You get that point right? In WoW there are A TON of attributes, so it would suck that I would have to create an if-statement for each, because there are simply too many. It's basically repeating itself, but still using the property name all the way. Here is what my JSFiddle looks like: http://jsfiddle.net/pm2328hx/ so you can play with it yourself. Thanks!
EDIT: Oh by the way, what I want to do is something like this:
if(property == "agility" || property == "stamina" || ....) {
text = "+" + text + " " + THE_ABOVE_VARIABLE_WHICH_IS_TRUE;
}
Which is hacky as well. I definitely don't want that.
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property;
}
If you need the first letter capitalized :
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per comment:
If you already have an array of all the attributes somewhere, use that instead
var myatts = [
'agility',
'stamina',
'dodge'
];
if(myatts.indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per next comment:
If you already have an object with the attributes as keys, you can use Object.keys(), but be sure to also employ hasOwnProperty
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
var property = "agility";
var text = "";
if(Object.keys(item.attribute).indexOf(property) !== -1){
if(item.attribute.hasOwnProperty(property)){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
Fiddle: http://jsfiddle.net/trex005/rk9j10bx/
UPDATE to answer intended question instead of asked question
How do I expand the following object into following string? Note: the attributes are dynamic.
Object:
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
String:
+ 100 Agility + 200 Stamina + 300 Dodge
Answer:
var text = "";
for(var property in item.attribute){
if(item.attribute.hasOwnProperty(property)){
if(text.length > 0) text += " ";
text += "+ " + item.attribute[property] + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
It's unclear how you're getting these values an storing them internally - but assuming you store them in a hash table:
properties = { stamina: 10,
agility: 45,
...
}
Then you could display it something like this:
var text = '';
for (var key in properties) {
// use hasOwnProperty to filter out keys from the Object.prototype
if (h.hasOwnProperty(k)) {
text = text + ' ' h[k] + ' ' + k + '<br/>';
}
}
After chat, code came out as follows:
var item = {};
item.name = "Thunderfury";
item.rarity = "legendary";
item.itemLevel = 80;
item.equip = "Binds when picked up";
item.unique = "Unique";
item.itemType = "Sword";
item.speed = 1.90;
item.slot = "One-handed";
item.damage = "36 - 68";
item.dps = 27.59;
item.attributes = {
agility:100,
stamina:200,
dodge:300
};
item.durability = 130;
item.chanceOnHit = "Blasts your enemy with lightning, dealing 209 Nature damage and then jumping to additional nearby enemies. Each jump reduces that victim's Nature resistance by 17. Affects 5 targets. Your primary target is also consumed by a cyclone, slowing its attack speed by 20% for 12 sec.";
item.levelRequirement = 60;
function build() {
box = $('<div id="box">'); //builds in memory
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key === 'attributes') {
for (var k in item.attributes) {
if (item.attributes.hasOwnProperty(k)) {
box.append('<span class="' + k + '">+' + item.attributes[k] + ' ' + k + '</span>');
}
}
} else {
box.append('<span id="' + key + '" class="' + item[key] + '">' + item[key] + '</span>');
}
}
}
$("#box").replaceWith(box);
}
build();
http://jsfiddle.net/gp0qfwfr/5/