6

I tried to set some json data inside a dataset attribute.

The HTML looks likes this

<div data-switch="true" data-json="{'key1': 'value 1'}, {'key2': 'value 2'}">

The data inside the data-json I obtain it with JavaScript in this way:

var json = $("[data-json]").data("json").toString();
json = JSON.stringify(json);

Whatever I try, it doesn't convert it to an object. It just returns a string

With toString() and stringify()

$(function() {
	json = $("[data-json]").data("json").toString();
    json = JSON.stringify(json);
    json = JSON.parse(json);
    
    console.log(json);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-json="{'key1': 'value 1'}, {'key2', 'value 2'}">

</div>

When i remove the toString() and stringify() functions, it gives the following error: Uncaught SyntaxError: Unexpected token ' in JSON at position 1

Without toString() and stringify()

$(function() {
	json = $("[data-json]").data("json");
    json = JSON.parse(json);
    
    console.log(json);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-json="{'key1': 'value 1'}, {'key2', 'value 2'}">

</div>

Fiddle with original JavaScript and HTML

/**
 * Switch content inside Metro UI blocks
 *
 * @requires {data-switch} 		Set data-switch="true" inside the dom
 */
$(function() {
	
	/**
	 * Get all switch elements
	 */
	var switches = $("[data-switch]");
	/**
	 * Sample data for each switch element	 
	var switches_data = {
		0: {
			0: {
				image: 'https://cdn.elegantthemes.com/blog/wp-content/uploads/2016/02/rules-good-ui-design-web-project-thumbnail.png',
				content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
			},
			1: {
				image: 'http://www.fujitsu.com/fts/Images/28618-workplace-manager580x224_tcm21-1830661.jpg',
				content: 'Aliquam interdum sit amet nibh aliquet accumsan.'
			},
			2: {
				image: 'http://cdn.moneycrashers.com/wp-content/uploads/2013/03/manager2.jpg',
				content: 'Vestibulum sed metus eu justo sagittis congue.'
			}
		},
		1: {
			0: {
				image: 'https://cdn.elegantthemes.com/blog/wp-content/uploads/2016/02/rules-good-ui-design-web-project-thumbnail.png',
				content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
			},
			1: {
				image: 'http://www.fujitsu.com/fts/Images/28618-workplace-manager580x224_tcm21-1830661.jpg',
				content: 'Aliquam interdum sit amet nibh aliquet accumsan.'
			},
			2: {
				image: 'http://cdn.moneycrashers.com/wp-content/uploads/2013/03/manager2.jpg',
				content: 'Vestibulum sed metus eu justo sagittis congue.'
			}
		},
		2: {
			0: {
				image: 'https://cdn.elegantthemes.com/blog/wp-content/uploads/2016/02/rules-good-ui-design-web-project-thumbnail.png',
				content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
			},
			1: {
				image: 'http://www.fujitsu.com/fts/Images/28618-workplace-manager580x224_tcm21-1830661.jpg',
				content: 'Aliquam interdum sit amet nibh aliquet accumsan.'
			},
			2: {
				image: 'http://cdn.moneycrashers.com/wp-content/uploads/2013/03/manager2.jpg',
				content: 'Vestibulum sed metus eu justo sagittis congue.'
			}
		}
	};
	*/
	/**
	 * Check if elements exists
	 */
	if(switches.length > 0) {
		/**
		 * Loop through objects
		 *
		 * @var c 	Object Key
		 * @var e 	Object Value
		 */
		$.each(switches, function(c, e) {
			/** 
			 * Get switches data current object
			 */
			var switches_data = $(this).data("switches");
			console.log(switches_data);
			/**
			 * Get next div
			 */
			var next = $(this).children().first()[0];
			next = $(next);
			/**
			 * Set type animation
			 */
			var animation = "flipInX";
			/**
			 * Set index where to start from
			 */
			var index = 0;
			/**
			 * Generate interval seconds, a random number so they will never be the same
			 */
			var x = Math.floor((Math.random() * 6000) + 3000);
			/**
			 * Loop through switches
			 *
			 * @var i 	Object Key
			 * @var b	Object Value
			 */
			$.each(switches_data, function(i, b) {
				/**
			 	 * Create new element for each switches
			 	 */
				var el = $("<div />").attr({class: "metro-ui-column-content animated", id: "content-column-" + i});
				/**
				 * Append el to next element, previous defined
				 */
				el.appendTo(next);
				/**
				 * Set background image for el
				 */
				el.css({
					"background": "url("+ b.image +") no-repeat",
					"background-size": "cover"
				});
				/**
				 * Append html content
				 */
				el.html( "<div class=\"metro-ui-column-html\">" + b.content + "</div>");
			});
			
			/**
			 * Set static this
			 */
			var self = $(this);
			/**
			 * Find all animated object
			 */
			var animated = $(this).find(".animated");
			/**
			 * Generate random number between 2000 and 4000, it acts as seconds for interval
			 */
			var x = Math.floor((Math.random() * 8000) + 4000);
			/**
			 * Loop through animated objects
			 *
			 * @var i	Object Key
			 * @var e	Object Value
			 */
			$.each(animated, function(i, e) {
				/**
				 * Start with the first animated object in the current loop
				 */ 
				if(i === 0) {
					/**
					 * Start with an timeout with random generated content, so no content will ever be loaded at the same time
					 */
					setTimeout(function() {
						/**
					 	 * Gets visible by setting the z-index
					 	 */
						$(e).css("z-index", 2).addClass("flipInX");
					}, x);
				}				
			});
			/**
			 * Set new index higher than first object
			 */
			var index = 3 ;
			/**
			 * Set interval function to start looping the animation
			 */
			setInterval(function() {
				/**
				 * Get next object from current object
				 */
				var next = self.find(".flipInX").next();
				/**
				 * If there is no next object reset to first object
				 */
				if(next.length === 0) {
					/**
					 * Update next to first object cause next doenst exist
					 */
					var next = self.find(".animated").first();
				}
				/**
				 * Set new index and add animation class
				 */
				next.css("z-index", index++).addClass("flipInX").siblings().removeClass("flipInX");
			}, x);
		});
	}
	
});
@import url('https://fonts.googleapis.com/css?family=Roboto:400,700');
body {
  background-color: #f1f1f1;
  font-family: 'Roboto', sans-serif;
  font-size: 14px;
}
* {
  box-sizing: border-box;
}
/* Metro theme UI */
.metro-theme-ui {
  max-width: 450px;
  margin: 40px auto;
  height: 250px;
}
.metro-ui-row {
  position: relative;
  width: 100%;
  min-height: 1px;
  /* Fix breaking when height is 0 */
}
.metro-ui-row:after,
.metro-ui-row:before {
  display: table;
  content: " ";
  clear: both;
}
.metro-ui-column {
  position: relative;
  background: #12A7CC;
  padding: 50px;
  box-shadow: 1px 1px 2px #ccc;
  overflow: hidden;
}
.metro-ui-column.fadeIn {
  animation: fadeIn .33s ease;
}
.metro-ui-column.fadeOut {
  animation: fadeOut .33s ease;
}
.metro-ui-column .metro-ui-column-content {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
}
.metro-ui-column .metro-ui-column-html {
  background: rgba(0, 0, 0, 0.5);
  position: absolute;
  color: #fff;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  padding: 10px;
}
/* Calculate column width */
.metro-ui-col {
  padding: 2px;
  float: left;
}
.metro-ui-col-10 {
  width: calc(100%);
}
.metro-ui-col-9 {
  width: calc(11.11111111%);
}
.metro-ui-col-8 {
  width: calc(12.5%);
}
.metro-ui-col-7 {
  width: calc(14.28571429%);
}
.metro-ui-col-6 {
  width: calc(16.66666667%);
}
.metro-ui-col-5 {
  width: calc(20%);
}
.metro-ui-col-4 {
  width: calc(25%);
}
.metro-ui-col-3 {
  width: calc(33.33333333%);
}
.metro-ui-col-2 {
  width: calc(50%);
}
.metro-ui-col-1 {
  width: calc(100%);
}
/* Keyframes */
.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
.animated.infinite {
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
.animated.hinge {
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
}
.animated.flipOutX,
.animated.flipOutY,
.animated.bounceIn,
.animated.bounceOut {
  -webkit-animation-duration: .75s;
  animation-duration: .75s;
}
@keyframes flipInX {
  from {
    left: -100%;
  }
  to {
    left: 0;
  }
}
.metro-ui-column .metro-ui-column-content.flipInX {
  -webkit-animation-name: flipInX;
  animation-name: flipInX;
  -webkit-backface-visibility: visible !important;
  backface-visibility: visible !important;
}
@keyframes flipOutX {
  from {
    -webkit-transform: perspective(400px);
    transform: perspective(400px);
  }
  30% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 0deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 0deg);
    opacity: 1;
  }
  to {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    opacity: 0;
  }
}
.flipOutX {
  -webkit-animation-name: flipOutX;
  animation-name: flipOutX;
  -webkit-backface-visibility: visible !important;
  backface-visibility: visible !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="metro-theme-ui">
	<div class="metro-ui-row">
		<div class="metro-ui-col metro-ui-col-10">
			<div class="metro-ui-column"></div>
		</div>
	</div>
	<div class="metro-ui-row">
		<div class="metro-ui-col metro-ui-col-3" data-switch="true" data-switches='{"image": "https://cdn.elegantthemes.com/blog/wp-content/uploads/2016/02/rules-good-ui-design-web-project-thumbnail.png", "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."}, { "image": "http://www.fujitsu.com/fts/Images/28618-workplace-manager580x224_tcm21-1830661.jpg", "content": "Aliquam interdum sit amet nibh aliquet accumsan."}, { "image": "http://cdn.moneycrashers.com/wp-content/uploads/2013/03/manager2.jpg", "content": "Vestibulum sed metus eu justo sagittis congue." }'">
			<div class="metro-ui-column"></div>
		</div>
		<div class="metro-ui-col metro-ui-col-3">
			<div class="metro-ui-column"></div>
		</div>
		<div class="metro-ui-col metro-ui-col-3">
			<div class="metro-ui-column"></div>
		</div>
	</div>
	<div class="metro-ui-row">
		<div class="metro-ui-col metro-ui-col-3">
			<div class="metro-ui-column"></div>
		</div>
		<div class="metro-ui-col metro-ui-col-3">
			<div class="metro-ui-column"></div>
		</div>
		<div class="metro-ui-col metro-ui-col-3">
			<div class="metro-ui-column"></div>
		</div>
	</div>
</div>

5
  • 2
    This json is invalid, is it the actual json you're using (to test) or do you have a real example? Commented May 8, 2017 at 13:06
  • Also you have a comma after key2, whereas it should be a colon : Commented May 8, 2017 at 13:13
  • @LiamMacDonald codepen.io/richardmauritz/pen/WjZJOp Commented May 8, 2017 at 13:14
  • 1
    @RichardMauritz add square brackets around your JSON (so encapsulate the 3 objects in to an array) Commented May 8, 2017 at 13:17
  • @rishipuri Sorry, that was a type. Anyway, [] around it did the job. Thanks guys Commented May 8, 2017 at 13:24

2 Answers 2

8

You can actually just pass a valid json object it should just work.

json = $("[data-json]").data("json");

console.log(typeof(json))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-switch="true" data-json='[{"key1": "value 1"}, {"key2": "value 2"}]'>

Sign up to request clarification or add additional context in comments.

4 Comments

I agree this is the issue. I'd suggest the poster uses a JSON validator to check in future - it's easy to miss simple things! jsonformatter.curiousconcept.com
Thank you sir, just adding brackets [] did the job ;)
Well spotted, I should have used the OP's JSON in my examples, I would have noticed... :-)
Thank you. This answer helped me. My problem was to use data-json='@Html.Raw(JsonConvert.SerializeObject(Model.PairValidationDropdown))' - solution was using single ' quote insted of double " for data-json attribute it self. P.S. @Html.Raw added automaticly the [] for json.
6

You use valid JSON (which requires that you use double quotes, not single quotes, around keys and other strings). Then either retrieve with attr and parse with JSON.parse, or if you want to use jQuery's data store, use data to load it into that store and access it; data will parse it automatically. Note that data is not just an accessor for data-8 attributes, it's both more and less than that, so be sure to read the API docs for it and use it if you want its features, and don't use it if you don't.

Example:

var d = $("div[data-json]");
// Using `attr` and `JSON.parse`:
console.log(JSON.parse(d.attr("data-json")));
// Using jQuery'd data store
console.log(d.data("json"));
<div data-json='{"answer":42,"question":"Life, the Universe, and Everything!"}'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Note that the attribute uses single quotes, so we can conveniently use double quotes in the JSON. But that would fail if we used ' in the JSON anywhere (such as in a string: "where":"Joe's house").

The text of attributes is HTML, not raw text. So if you're generating this JSON dynamically, perhaps in a server-side template or something, be sure that when it's output, it's output as HTML text, not raw text, to ensure that any necessary encoding is done. When you do that, the quotes may well be turned into &quot; entities, in which case there's no problem using " around the attribute value:

var d = $("div[data-json]");
// Using `attr` and `JSON.parse`:
console.log(JSON.parse(d.attr("data-json")));
// Using jQuery'd data store
console.log(d.data("json"));
<div data-json="{&quot;answer&quot;:42,&quot;question&quot;:&quot;Life, the Universe, and Everything!&quot;}"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

8 Comments

Can you give an example? I tried to use double quotes, however i keep getting the same error. <-- nvm, you just wrote one ;)
@RichardMauritz: Added an example.
Can you check out this codepen.io/richardmauritz/pen/WjZJOp? I can't get it working. I tried to do double quotes
@RichardMauritz: I wondered if you might be having quotes problems and added a note to the above. Re CodePen: The full content of your question must be in your question, not just linked. (And it would need to be a minimal reproducible example, rather than the full thing.)
I just had to add [] arround it, like @rishipuri awnsered. It worked. Thanks anyway for your explanation.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.