How do I get the options from another set of options.
JS Fiddle Example
at the moment this is outputting the name of each option in opt.social. Instead I want it to fetch the actual HTML related to each option name.
Thus the idea is that in the future when a new social media site is built, this can easily be added via the plugin options without the need to edit the plugin.
Example:
$.each(opt.social, function(index, value) {
html += "<li>" + value.name + "</li>";
});
I have tried
opt[value.name];
opt.value.name;
opt(value.name);
Full example:
(function ($) {
$.fn.socialMedia = function (options) {
// default configuration properties
var defaults = {
social: [
{ name: "facebook.like_large"},
{ name: "twitter.large"},
{ name: "googlePlus.large"}
],
facebook: {
like_large: '<div class="fb-like" data-href="{url}" data-send="false" data-layout="box_count" data-width="120" data-show-faces="false"></div>',
like_small: '<div class="fb-like" data-href="{url}" data-send="false" data-layout="button_count" data-width="120" data-show-faces="false" data-colorscheme="dark"></div>',
share: '<a name="fb_share" type="box_count" share_url="{url}" href="http://www.facebook.com/sharer.php?u={url}&t={title}">Share</a>'
},
twitter: {
large: 'Tweet',
small: 'Tweet'
},
googlePlus: {
large: '<div class="g-plusone" data-size="tall" data-href="{url}"></div>',
small: '<div class="g-plusone" data-size="medium" data-annotation="inline" data-width="120" data-href="{url}"></div>'
}
};
var opt = jQuery.extend(defaults, options);
// Generate HTML
$(this).append(generateHtml());
function generateHtml() {
var html = '<ul>';
$.each(opt.social, function(index, value) {
html += "<li>" + value.name + "</li>";
});
html += '</ul>';
return html;
}
}
$("body").socialMedia();
})(jQuery);
In that code, opt.social is an array of objects, each with a "name" property.
Thus,
var firstOptName = opt.social[0].name;
And so on. The opt.social array should be indexed numerically. Now, opt.googlePlus is just an object with (in this case) two properties, so there's no array indexing involved:
var googleLarge = opt.googlePlus.large;
edit — if you want to just alter that loop to show the HTML:
$.each(opt.social, function(index, value) {
var parts = value.name.split('.'), partVal = opts;
for (var i = 0; i < parts.length; ++i)
partVal = partVal[parts[i]];
html += "<li>" + partVal + "</li>";
});
The trick is that those "name" properties are in the form of dotted "paths" through an object graph, and JavaScript does not have a built-in way of interpreting those. The code I wrote above walks through the object part by part (parts are separated by "." characters), starting from the outer "opts" object.
I've updated your fiddle, according to what I understood you wanted.
each social entry can contain the name of the social service and a default widget to use.
so your defaults can be like this:
social: [
{ name: 'facebook', widget : 'like_large'},
{ name: 'twitter', widget : 'large'},
{ name: 'googlePlus', widget : 'large'}
]
and your generateHTML() can be:
$.each(opt.social, function(index, value) {
var default_widget = opt[value.name][value.widget];
html += "<li>" + default_widget + "</li>";
// or maybe:
html += $('<li></li>').html(default_widget);
});
Related
I need to store a Javascript object into a div (or in production: many divs). It really needs to go into the data-object="" attribute – i don't want to add it later via $('div').data('object').
The below code only returns "{"... I feel like I have tried every combination of stringify and parse and whatnot.
Does anybody have a clue how to retrieve my object?
var Module = {
div: function() {
var object = {
name: 'one',
type: 'two'
};
var html = '<div data-object="' + JSON.stringify(object) + '"></div>';
var div = $(html).appendTo('body');
// This just returns "{" instead of my object
console.log(div.data('object'));
}
}
$(document).click(function() {
Module.div();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is because JSON gets encoded using double quotes ", and you also encapsulate it between double quotes. The problem with this is that it produces :
<div data-object="{" name":"one","type":"two"}"></div>
so, when you read data-object, its value is effectively "{".
Try encapsulating it into simple quotes :
var Module = {
div: function() {
var object = {
name: 'one',
type: 'two'
};
var html = "<div data-object='" + JSON.stringify(object) + "'></div>";
var div = $(html).appendTo('body');
// This just returns "{" instead of my object
console.log(div.data('object'));
}
}
$(document).click(function() {
Module.div();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Now the output is valid :
<div data-object='{"name":"one","type":"two"}' ></div>
You can also set the attribute programmatically with jQuery :
var Module = {
div: function() {
var object = {
name: 'one',
type: 'two'
};
var div = $("<div>")
.attr("data-object", JSON.stringify(object))
.appendTo('body');
console.log(div.data('object'));
}
}
$(document).click(function() {
Module.div();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Replace var html = '<div data-object="' + JSON.stringify(object) + '"></div>';
With var html = '<div data-object=' + JSON.stringify(object) + '></div>';
No need to add the additional double quotes
var Module = {
div: function() {
var object = {
name: 'one',
type: 'two'
};
var html = '<div data-object=' + JSON.stringify(object) + '></div>';
var div = $(html).appendTo('body');
// This just returns "{" instead of my object
console.log(div.data('object'));
}
}
$(document).click(function() {
Module.div();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
</body>
I'm getting JSON data from the API, like this
data = {
q: 'sugar',
from: 0,
to: 10,
params: {
sane: [],
q: [ 'sugar' ]
},
more: true,
count: 1000,
hits: [{
recipe: {
uri: 'http://www.edamam.com/ontologies/edamam.owl#recipe_a46ae0ad4f8320fa6285b25fc7b36432',
label: 'Bread Pudding with Apple and Brown Sugared Bacon',
image: 'https://www.edamam.com/web-img/1ae/1ae111af3737d42e9d743445f5605373.JPG '
},
recipe: {
uri: 'http://www.edamam.com/ontologies/edamam.owl#recipe_a36b51f50f102bf5da228af55d2ce040',
label: 'Vanilla sugar',
image: 'https://www.edamam.com/web-img/4fd/4fdd2336043aa81dd05a4b6a08934402.jpg',
}
}]
}
And I try to bind the recipe to divs. For example, there is a div with the id columns,
Here is that piece of codes.
var list = data.hits;
function Builddivs(list) {
var array = new Array(0);
var count = list.length;
for (var i = 0; i < 10; i++) {
var p = list[i];
title = p.recipe.label;
imgurl = p.recipe.image;
href = p.recipe.url;
array.push("<div class='pin'><a href='" + href + "'><img src='" + imgurl + "'/></a><p>" + title + "</p> </div>");
}
var html = array.join("");
$("#columns").html(html);
}
The problem is to generate that html takes like several seconds, so is there a better way to do that? like bind the data directly to existing dynamic number of divs? Thanks!
Instead of generating a lot of HTML at once, it would be more efficient to edit existing HTML.
Example jsfiddle solution to this question
Editing HTML with jQuery
You can replace or add text or HTML to a div:
$(selector).html('Try <span class="red">this!</span>');
$(selector).text('Just add some text');
$(selector).append('Some HTML');
Adding src to an image or adding href to a link:
$(selector).attr('src','http://example.com/someimage.jpg');
$(selector).attr('href','http://example.com');
Instead of using a for loop, you could use javascript Array.forEach or jquery $.each
Generating HTML for the first time
On every run (every time the list changes) you can check if the HTML element to be edited exists. If not, then you can generate the appropriate HTML. On the first run of the code, the HTML would then be generated for every element from the list.
See this question to see how to check if elements exist:
How do you check if a selector matches something in jQuery?
Example
Here is a working jsfiddle with an example of how HTML can be edited using $().attr and $().html: https://jsfiddle.net/fyux250p/1/
var hitsContent =""
(list || []).forEach(function(data,index){
hitsContent += "<div class='pin'><a href='" + data.url + "'><img src='" + data.url + "'/></a><p>" + data.label + "</p> </div>";
})
$("#columns").html(hitsContent);
Fiddle Example
The following is an example where several buttons are rendered via a loop. I was wondering if it is possible to bind events to each button as well during the loop before the buttons are appended to a container. My example doesn't work.
Jquery
function render(){
var input = '',
array = [{'name':'Confirm','title':'This'},{'name':'Cancel','title':'That'}]
$.each(array,function(k,obj){
var name = obj.name;
input += '<h3>'+obj.title+'</h3>';
input += '<input type="submit" name="'+name+'" value="'+name+'"/>';
$(input).find('[name="'+name+'"]').click(function(){
alert(name)
/*** do some ajax things etc ***/
})
})
return input;
}
$('#box').append(render())
Yes but I wouldn't do it the way you are:
function render(target){
var array = [{'name':'Confirm','title':'This'},{'name':'Cancel','title':'That'}]
$.each(array,function(k,obj){
var name = obj.name;
var h3 = $('<h3/>').text(obj.title);
var input = $('<input/>')
.attr('type', 'submit')
.attr('name',name)
.val(name);
input.click(function() {alert('test');});
target.append(h3);
target.append(input);
})
}
$(document).ready(function(){
render($('#box'));
});
So create jquery objects that will be rendered, then attach the event to these objects. Then once the object is built ask jquery to render them.
This way jquery can keep track of the DOM elements, in your example your stringfying everything. Jquery hasn't built the DOM element at the point where your attempting to bind to them.
Fiddle
You need to use filter() to find the element by the name as there is no parent selector to find() within:
$(input).filter('[name="' + name + '"]').click(function(){
alert(this.name)
/*** do some ajax things etc ***/
})
No, you can't bind event handlers to strings. You will need to create HTML elements first. I would recommend to bind single delegated event handler after your HTML string is appended, it's also going to be much better in terms of performance:
function render() {
var input = '',
array = [{'name': 'Confirm','title': 'This'}, {'name': 'Cancel','title': 'That'}]
$.each(array, function (k, obj) {
var name = obj.name;
input += '<h3>' + obj.title + '</h3>';
input += '<input type="submit" name="' + name + '" value="' + name + '"/>';
});
return input;
}
$('#box').append(render()).on('click', 'input[name]', function() {
alert(this.name);
/** do some ajax things etc **/
});
Demo: http://jsfiddle.net/KHeZY/200/
This can be done properly by using event-delegation, But since you concerned, I just written a solution by using .add() and .filter()
function render() {
var input = '',
array = [{
'name': 'Confirm',
'title': 'This'
}, {
'name': 'Cancel',
'title': 'That'
}],
elem = $();
$.each(array, function (k, obj) {
var name = obj.name;
input += '<h3>' + obj.title + '</h3>';
input += '<input type="submit" name="' + name + '" value="' + name + '"/>';
elem = elem.add($(input));
input = "";
});
elem.filter("[name]").click(function () {
alert(this.name);
})
return elem;
}
$('#box').append(render())
DEMO
I cannot figure out for the life of me why this will not work. I am trying to pull the value of a textfield that was created with a loop from a json file.
In this code, at the very bottom I just do a simple click(function() {alert()} just to see if I can pull a value and its returning undefined. But if I remove '#name' and put in 'input' it captures it, but only for the first of several input fields.
Any help is really appreciated
JSON
{
"Controls": [{
"Button":[{ "Name":"Button", "x": "1","y": "2","width": "3","height": "4","Transition":"" }],
"Image":[{"x": "5","y": "6","width": "7","height": "8"}],
"TextField":[{"x": "9","y": "10","width": "11","height": "12","Rows":""}]
}]
}
The Code(there is soome getJSON stuff above this)
//Slide In Attributes Panel Based on Selected Object
$(document).on('click', '#code li', function () {
var index = $('#code li').index(this);
var selected = $(this).text();
switch (selected) {
case selected:
$('#options').hide();
hidePanels();
$('#temp').remove();
$('#objectAttributes').show("slide", 200);
break;
//If it does work show what variable is being used
default:
alert(selected);
break;
}
//Shows Selected LI Index
$('#codeIndex').text("That was div index #" + index);
//Pull list of Attributes for selected Object
$.getJSON('controls.json', function (data) {
//Build Attributes List
var attributeList = '<div id="temp">';
//Target based on selected object
var target = selected;
attributeList += '<div>' + target + '<div>';
$.each(data.Controls[0][target][0], function (kk, vv) {
attributeList += '<div style="float:right">' + kk + ':' + '<input type="text" id='+ kk + '>' + '</input>' + '</div>';
});
attributeList += '</div></div>';
attributeList += '</div>';
$('#objectAttributes').append(attributeList);
$('#temp').append('<div id="editIndex">'+"Modifying index" + " " +index+'</div>');
$(document).on('click', '#saveAttributes', function () {
var $x = $('#name').val();
alert($x);
})
});
});
Ok, so after a little hacking around with a jsfiddle the answer turned out to be a lot simpler than I first thought. Ever since HTML 4.01 class names and IDs have been case sensitive (reference), which means that your selector $('#name') wasn't matching the JSON Name.
So a simple change, such as in this simplified jsfiddle seems to work as desired. Hopefully this helps!
I'm not any good at JavaScript (yet!) - I really need some help to get past this stuck point that is causing me lots of premature hair loss!
I just can't seem to figure out how to build the following HTML code using JSON data.
This is a sample of the JSON data that I have being generated for the new version of this page I'm working on:
[{"id":"1732","name":"1BR House","checkin":"2012-12-20","checkout":"2012-12-23","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1587","name":1BR House","checkin":"2012-12-23","checkout":"2013-01-01","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1661","name":"2BR Studio","checkin":"2012-12-25","checkout":"2013-01-02","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1829","name":"Studio Cottage","checkin":"2012-12-25","checkout":"2012-12-29","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1787","name":"Studio Cottage","checkin":"2012-12-29","checkout":"2013-01-08","inclean_cleaner":"","inclean_datetime":"2012-12-29 00:00:00","inclean_notes":""},{"id":"1843","name":"1BR House","checkin":"2013-01-07","checkout":"2013-01-19","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1970","name":"Studio Cottage","checkin":"2013-01-12","checkout":"2013-01-19","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1942","name":"Suite","checkin":"2013-01-15","checkout":"2013-01-20","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""}]
To illustrate the HTML result I need, here is how I currently do it without JSON (strictly in PHP):
<div class="'.$dashboard_list_line_class.'">
<div class="dashboard_list_unitname"> '.$unit_name.'</div>
<div class="dashboard_list_cleaner_datetime"> '.$inclean_datetime.'</div>
<div class="dashboard_list_cleaner_checkin"> '.$checkin.'</div>
<div class="dashboard_list_cleaner_checkout"> '.$checkout.'</div>
<div class="dashboard_list_cleaner_inclean_cleaner"> '.$inclean_cleaner.'</div>
<div class="dashboard_list_cleaner_notes"> '.$inclean_notes.'</div>
</div>
What would the code look like in jQuery or JavaScript to grab the JSON, iterate though the arrays and create the same result as the PHP I have shown? I've been trying for hours, and get different results of puling data - but I just can't make it work.
Thanks for your help!
Here is you complete solution:
$.ajax( "example.php" ).done(function (response) {
//var data = [{"id":"1732","name":"1BR House","checkin":"2012-12-20","checkout":"2012-12-23","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1587","name":"1BR House","checkin":"2012-12-23","checkout":"2013-01-01","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1661","name":"2BR Studio","checkin":"2012-12-25","checkout":"2013-01-02","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1829","name":"Studio Cottage","checkin":"2012-12-25","checkout":"2012-12-29","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1787","name":"Studio Cottage","checkin":"2012-12-29","checkout":"2013-01-08","inclean_cleaner":"","inclean_datetime":"2012-12-29 00:00:00","inclean_notes":""},{"id":"1843","name":"1BR House","checkin":"2013-01-07","checkout":"2013-01-19","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1970","name":"Studio Cottage","checkin":"2013-01-12","checkout":"2013-01-19","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""},{"id":"1942","name":"Suite","checkin":"2013-01-15","checkout":"2013-01-20","inclean_cleaner":"","inclean_datetime":"0000-00-00 00:00:00","inclean_notes":""}];
var data = $.parseJSON(response);
var dashboard_list_unitname = 'change_this';
var booking_id = 'also_change_this';
$(data).each(function (i, row) {
$(row).each(function (j, col) {
var html = '<div class="row_' + i + '">' +
'<div class="' + dashboard_list_unitname + '"> ' + col.name + '</div>' +
'<div class="dashboard_list_cleaner_datetime"> ' + col.inclean_datetime + '</div>' +
'<div class="dashboard_list_cleaner_checkin"> ' + col.checkin + '</div>' +
'<div class="dashboard_list_cleaner_checkout"> ' + col.checkout + '</div>' +
'<div class="dashboard_list_cleaner_inclean_cleaner"> ' + col.inclean_cleaner + '</div>' +
'<div class="dashboard_list_cleaner_notes"> ' + col.inclean_notes + '</div>' +
'</div>';
$('body').append($(html));
});
});
});
jQuery templates can help here.
http://api.jquery.com/jquery.tmpl/ shows several examples of a template being populated from a JSON-like data bundle, and the {{each}} element allows you to iterate over lists to populate rows and cells.
Template:
<li>
Title: ${Name}.
{{each Languages}}
${$index + 1}: <em>${$value}. </em>
{{/each}}
</li>
Data:
var movies = [
{ Name: "Meet Joe Black", Languages: ["French"] },
{ Name: "The Mighty", Languages: [] },
{ Name: "City Hunter", Languages: ["Mandarin", "Cantonese"] }
];
Everyone seems to be assuming knowledge of AJAX calls. It's not complicated, here is an example,
$.get('json/url', function(json_data) {
// do stuff with your data
// like, other people suggested json_data.each(function(item) {
// do stuff
// });
});
You can learn more about it straight from the jQuery docs,
http://api.jquery.com/jQuery.get/
If you need to make a post request just consult the jQuery docs for post, or for the more general article, the jQuery docs for AJAX calls: http://api.jquery.com/jQuery.ajax/.
var table = '';
$.each(json_data, function(index, obj) {
table += '<div>';
for(var x in obj) {
table += '<div class="dashboard_list_unitname"> '+ obj[x]+'</div>';
}
table += '</div>';
});