This seems in my head like it should work but I cant figure out why it doesn't:
(function ($) {
$.fn.extend({
facebook: function (opts, callbackFnk) {
var $this = this;
...
...
...
$this.fbGetFriends = function( clback ){
jsonUrl = fbMe + '/friends?access_token=' + token + '&callback=?';
$.getJSON( jsonUrl, function( json ){
console.log(json.data[0].name);
clback.call(json);
});
}
...
...
...
In the console log the first name appears
In my other script:
var facebook = $.fn.facebook(
{
myClientId : '###############',
mySecret : '##############'
}
);
facebook.fbOnLogin = function(){
user = facebook.userDetails();
token = facebook.getToken();
facebook.fbGetFriends(function( json ){
for ( var i in json ) {
console.log( 'friends: ' + i + ' ' + json[i] );
}
});
}
In console log im getting nothing displayed and in previous tests its displaying errors data undefined.
Can anyone tell me where im going wrong?
regards
You don't need clback.call, just clback(json) is enough.
Related
I am using the ckfinder modal without CKEditor to upload multiple files to the form section.
I used the code provided in the documentation section,
CKfinder modal opens as expected, selected multiple file but i couldn't able to get all the images url. The response i got only the first image.
window.CKFinder = {
_popupOptions: {
'popup-1-config': { // Config ID for first popup
chooseFiles: true,
onInit: function( finder ) {
finder.on( 'files:choose', function( evt ) {
var file = evt.data.files.first();
var output = document.getElementById( 'output' );
output.innerHTML = 'Selected in popup 1: ' + file.get( 'name' ) + '<br>URL: <img src=" ' + file.getUrl() + '">';
} );
}
},
}
};
var popupWindowOptions = [
'location=no',
'menubar=no',
'toolbar=no',
'dependent=yes',
'minimizable=no',
'modal=yes',
'alwaysRaised=yes',
'resizable=yes',
'scrollbars=yes',
'width=800',
'height=600'
].join( ',' );
document.getElementById( 'popup-1-button' ).onclick = function() {
// Note that config ID is passed in configId parameter
window.open( 'http://foxhills.localhost/admin/ckfinder/ckfinder.html?popup=1&configId=popup-1-config', 'CKFinderPopup1', popupWindowOptions );
};
In the above code var file = evt.data.files.first(); is the reason why i am getting the first image. How i can change the code to get the all the urls as array.
For your event, try testing with this
finder.on( 'files:choose', function( evt ) {
var files = evt.data.files;
var chosenFiles = '';
files.forEach( function( file, i ) {
chosenFiles += ( i + 1 ) + '. ' + file.get( 'name' ) + '\n';
} );
alert( chosenFiles );
} );
Source: https://ckeditor.com/docs/ckfinder/ckfinder3/#!/api/CKFinder.Application-event-files_choose
I have added custom javascript code to the header.php file of my wordpress site. I have tested this code on a basic html file and it works fine, but I cannot seem to make the vote recording function work on a wordpress post. The other components of the script are working fine (hover, vote display from a .txt file), but I cannot get the function to record the vote working. All files have read/write access.
I would greatly appreciate it if anyone could assist me or point me in the right direction to solve this.
Here is the part of the script that records the vote, I am fairly new to php and was wondering if there is something I can add/replace to modify so the code so it will work properly on Wordpress.
$('.ratings_stars').bind('click', function() {
var star = this;
var widget = $(this).parent();
var clicked_data = {
clicked_on : $(star).attr('class'),
widget_id : $(star).parent().attr('id')
};
$.post(
'http://localhost/url/wordpress/wp-content/ratings.php',
clicked_data,
function(INFO) {
widget.data( 'fsr', INFO );
set_votes(widget);
},
'json'
);
});
});
function set_votes(widget) {
var avg = $(widget).data('fsr').whole_avg;
var votes = $(widget).data('fsr').number_votes;
var exact = $(widget).data('fsr').dec_avg;
window.console && console.log('and now in set_votes, it thinks the fsr is ' + $(widget).data('fsr').number_votes);
$(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
$(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote');
$(widget).find('.total_votes').text( votes + ' votes recorded (' + exact + ' rating)' );
}
Here is a visual example for reference
Thank you for taking time to look at this, if there is any additional information that I can provide please let me know.
Here is the ratings.php that was mentioned in the script that was placed in the header.php.
ratings.php:
<?php
$rating = new ratings($_POST['widget_id']);
isset($_POST['fetch']) ? $rating->get_ratings() : $rating->vote();
class ratings {
var $data_file = 'http://localhost/url/wordpress/wp-content/ratings.data.txt';
private $widget_id;
private $data = array();
function __construct($wid) {
$this->widget_id = $wid;
$all = file_get_contents($this->data_file);
if($all) {
$this->data = unserialize($all);
}
}
public function get_ratings() {
if($this->data[$this->widget_id]) {
echo json_encode($this->data[$this->widget_id]);
}
else {
$data['widget_id'] = $this->widget_id;
$data['number_votes'] = 0;
$data['total_points'] = 0;
$data['dec_avg'] = 0;
$data['whole_avg'] = 0;
echo json_encode($data);
}
}
public function vote() {
preg_match('/star_([1-5]{1})/', $_POST['clicked_on'], $match);
$vote = $match[1];
$ID = $this->widget_id;
if($this->data[$ID]) {
$this->data[$ID]['number_votes'] += 1;
$this->data[$ID]['total_points'] += $vote;
}
else {
$this->data[$ID]['number_votes'] = 1;
$this->data[$ID]['total_points'] = $vote;
}
$this->data[$ID]['dec_avg'] = round( $this->data[$ID]['total_points'] / $this->data[$ID]['number_votes'], 1 );
$this->data[$ID]['whole_avg'] = round( $this->data[$ID]['dec_avg'] );
file_put_contents($this->data_file, serialize($this->data));
$this->get_ratings();
}
}
?>
Here is the complete javascript code added to the header.php, the mouseover/mouseout seem to be working properly, so I think the javascript should be running.
Javascript added to header.php:
<?php wp_head(); ?>
<script type="text/javascript">
$(document).ready(function() {
$('.rate_widget').each(function(i) {
var widget = this;
var out_data = {
widget_id : $(widget).attr('id'),
fetch: 1
};
$.post(
'http://localhost/url/wordpress/wp-content/ratings.php',
out_data,
function(INFO) {
$(widget).data( 'fsr', INFO );
set_votes(widget);
},
'json'
);
});
$('.ratings_stars').hover(
function() {
$(this).prevAll().andSelf().addClass('ratings_over');
$(this).nextAll().removeClass('ratings_vote');
},
function() {
$(this).prevAll().andSelf().removeClass('ratings_over');
set_votes($(this).parent());
}
);
$('.ratings_stars').bind('click', function() {
var star = this;
var widget = $(this).parent();
var clicked_data = {
clicked_on : $(star).attr('class'),
widget_id : $(star).parent().attr('id')
};
$.post(
'http://localhost/url/wordpress/wp-content/ratings.php',
clicked_data,
function(INFO) {
widget.data( 'fsr', INFO );
set_votes(widget);
},
'json'
);
});
});
function set_votes(widget) {
var avg = $(widget).data('fsr').whole_avg;
var votes = $(widget).data('fsr').number_votes;
var exact = $(widget).data('fsr').dec_avg;
window.console && console.log('and now in set_votes, it thinks the fsr is ' + $(widget).data('fsr').number_votes);
$(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
$(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote');
$(widget).find('.total_votes').text( votes + ' votes recorded (' + exact + ' rating)' );
}
</script>
To solve this all I had to do was place my ratings.php file and ratings.data.txt within my wordpress theme folder and link the custom javascript to these files within my header.php file. The javascript now operates properly. This is not the proper way to do this though, ideally I should use the wp_enqueue_scripts hook in the header.php and have the custom css and js in the css/js folders. But for now this temporary fix works and I can continue experimenting.
I am trying to explicitly get the system properties from my table but it is not working. I can see that the URL is returning all the data including these fields if I use https://myservice.azure-mobile.net/tables/todoitem?__systemProperties=* but on the code I cannot get it as item.__version or item.version. I have tried adding todoitemtable = WindowsAzure.MobileServiceTable.SystemProperties.All; but no success! I have also looked at http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-validate-modify-data-server-scripts/ but this is adding a new column instead of using the existing system columns.
$(function() {
var client = new WindowsAzure.MobileServiceClient('https://ib-svc-01.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
// = WindowsAzure.MobileServiceTable.SystemProperties.All;
// Read current data and rebuild UI.
// If you plan to generate complex UIs like this, consider using a JavaScript templating library.
function refreshTodoItems() {
var query = todoItemTable.where({ complete: false });
query.read().then(function(todoItems) {
var listItems = $.map(todoItems, function(item) {
return $('<li>')
.attr('data-todoitem-id', item.id)
.append($('<button class="item-delete">Delete</button>'))
.append($('<input type="checkbox" class="item-complete">').prop('checked', item.complete))
.append($('<div>').append($('<input class="item-text">').val(item.id))
.append($('<span class="timestamp">'
+ (item.createdAt && item.createdAt.toDateString() + ' '
+ item.createdAt.toLocaleTimeString() || '')
+ '</span>')));
});
$('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
$('#summary').html('<strong>' + todoItems.length + '</strong> item(s)');
}, handleError);
}
function handleError(error) {
var text = error + (error.request ? ' - ' + error.request.status : '');
$('#errorlog').append($('<li>').text(text));
}
function getTodoItemId(formElement) {
return $(formElement).closest('li').attr('data-todoitem-id');
}
// Handle insert
$('#add-item').submit(function(evt) {
var textbox = $('#new-item-text'),
itemText = textbox.val();
if (itemText !== '') {
todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems, handleError);
}
textbox.val('').focus();
evt.preventDefault();
});
// Handle update
$(document.body).on('change', '.item-text', function() {
var newText = $(this).val();
todoItemTable.update({ id: getTodoItemId(this), text: newText }).then(null, handleError);
});
$(document.body).on('change', '.item-complete', function() {
var isComplete = $(this).prop('checked');
todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems, handleError);
});
// Handle delete
$(document.body).on('click', '.item-delete', function () {
todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems, handleError);
});
// On initial load, start by fetching the current data
refreshTodoItems();
});
I was trying to access the system properties from within the API scripts and found this and thought it was useful and relevant: http://www.brandonmartinez.com/2014/10/22/retrieve-system-properties-in-azure-mobile-services-javascript-backend/
Basically you can do this (example from the post):
myTable.read({
systemProperties: ['__createdAt', '__updatedAt'],
success: function(tableEntries) {
// So on and so forth
}
}
I have written my javascript too much, and now the code keeps repeating itself, whereas I lack of knowledge on how to simplify matters. I have this idea of calling variable into function, but I don't know how to call this kind of function that contains dynamic variables.
Anyone got any tips on how can I achieve this?
var container = '#content_container';
function container_load(){
var data = $(this).attr('data');
var dataObject = {command : data};
var title = '<h2 data="'+dataObject.command+'">'+
dataObject.command+'</h2>';
};
$(function(){
$('nav')on.('click', 'a', function(){
container_load();
$(container).prepend(title);
});
});
Apparently, console returned ReferenceError: Can't find variable: dataObject
There is two issue is in your code
var container = '#content_container';
var title; //title should be declare as global,same as "container" variable
function container_load(dis){
var data = dis.attr('data');
var dataObject = {command : data};
title = '<h2 data="'+dataObject.command+'">'+
dataObject.command+'</h2>';
}
$(function(){
$('nav').on('click', 'a', function(){
container_load($(this)); //you have to pass the current element
$(container).prepend(title);
});
});
Demo : Demo
Try this :
var container = '#content_container';
function container_load(currElementId){
var data = $("#"+currElementId).attr('data');
return '<h2 data="'+data+'">'+data+'</h2>';
};
$(function(){
$('nav')on.('click', 'a', function(){
var title = container_load(this.id);
$(container).prepend(title);
});
});
Here your problem is that you cannot 'this' in other function for that you need to pass it from your current function.
There seems to be few mistakes in your code, The scope is wrong and the data attribute is used not correctly I presume. I suppose this is what you wanted http://jsfiddle.net/EjEqK/2/
HTML
<nav >aaa</nav>
<div id="content_container"></div>
JS
function container_load() {
var data = $(this).data("val");
var dataObject = { command: data };
$("#content_container").prepend('<h2 data-val="' + dataObject.command + '">' + dataObject.command + '</h2>');
};
$(function () { $('nav > a').on('click', container_load); });
PS: If you don't need dataObject for anything else, directly use data
I think this will help you :
function container_load(currElement){
var data = $(currElement).attr('data');
return '<h2 data="'+data+'">'+data+'</h2>';
}
$(function(){
var container = '#content_container';
$('nav')on.('click', 'a', function(){
var title = container_load(this);
$(container).prepend(title);
});
});
You could do the following :
var container = '#content_container',
title; // make title global
function container_load() {
var data = $(this).attr('data');
var dataObject = { command: data };
title = '<h2 data="' + dataObject.command + '">' +
dataObject.command + '</h2>';
};
$(function () {
$('nav') on.('click', 'a', function () {
container_load.call(this); // bind this to container_load
$(container).prepend(title);
});
});
But you could do even better :
$(function () {
$('nav') on.('click', 'a', function () {
var data = $(this).attr('data');
$('#content_container').prepend(
'<h2 data="' + data + '">' + data + '</h2>'
);
});
});
I am using jQuery to create an anchor and bind it with JavaScript function as follow:
$(document).ready
(
function()
{
var test = function(arg)
{
alert(arg);
}
var anotherTest = function(arg)
{
do something;
}
$('#id').click
(
var content = "Hello world";
var anchor = "<a href='javascript:void(0);' onclick='test(\"" + content + "\")' >test</a>";
$('#DivToBind').prepend(anchor);
);
}
);
And the problem is: the test function always alerts "a", no matter what the value of content is. If I change onclick function test to anotherTest, nothing happens but "anotherTest is not defined" appeared in the error console
Edit
To better identify my problem, I summarise my real code as follow
$(document).ready
(
function()
{
var deleteComment = function (comment)
{
commentInfo = comment.split('_');
var postid = commentInfo[0];
var enum = commentInfo[1];
var parentid = commentInfo[2];
var user = commentInfo[3];
var author = commentInfo[4];
var date = commentInfo[5];
$.get
(
"ajaxhandle.php",
{ref: 'commentdelete', pid: postid, d: date},
function(text)
{
if (text)
{
//alert(comment);
$('#' + comment).html('');
}
else
{
alert("Something goes wrong");
}
},
'text'
);
};
var test = function(arg) {alert(arg);};
$('#postCommentButton').click
(
function ($e)
{
$e.preventDefault();
var comment = $('#postdata').val();
var data = $('form#commentContent').serialize();
//alert(data);
$.post
(
"ajaxhandle.php",
data,
function($xml)
{
$xml = $($xml);
if ($xml)
{
//alert(45);
var success = $xml.find("success").text();
if (success == 1)
{
$('#postdata').val("");
var id = $xml.find("id").text();
var reference = $xml.find("reference").text();
var parentid = $xml.find("parentid").text();
var user = $xml.find("user").text();
var content = $xml.find("content").text();
var authorID = $xml.find("authorid").text();
var authorName = $xml.find("authorname").text();
var converteddate = $xml.find("converteddate").text();
var date = $xml.find("date").text();
var avatar = $xml.find("avatar").text();
comment = id + '\_wall\_' + parentid + '\_' + user + '\_' + authorID + '\_' + date;
//alert(comment);
var class = $('#wallComments').children().attr('class');
var html = "<div class='comment' id='" + comment + "' ><div class='postAvatar'><a href='profile.php?id=" + authorID + "'><img src='photos/60x60/" + avatar +"' /></a></div><div class='postBody' ><div class='postContent'><a href='profile.php?id=" + authorID + "'>" + authorName + " </a> <span>" + content + "</span><br /><div class='timeline'>Posted " + converteddate + "<br /><a href=''>Comment</a> | <a href=''>Like</a> | <a href='javascript:void(0);' onclick='deleteComment(\"" + comment + "\")' class='commentDelete' >Delete</a></div></div></div><div style='clear:both'></div><hr class='hrBlur' /></div>";
if (class == 'noComment')
{
//alert($('#wallComments').children().text());
//alert(comment);
$('#noComment').html('');
$('#wallComments').prepend(html);
}
else if(class = 'comment')
{
//alert(comment);
$('#wallComments').prepend(html);
}
}
else
{
alert("Something goes wrong");
}
}
else
alert("Something goes wrong");
},
'xml'
);
}
);
$(".comment").find('.commentDelete').click
(
function($e)
{
$e.preventDefault();
var comment = $(this).parent().parent().parent().parent().attr('id');
deleteComment(comment);
}
);
}
);
var test=... is inside a function, it's not going to be in scope on the page when you want to call it onclick the anchor.
to make it global you can leave off the var.
you could also do something like:
$(document).ready
(
function()
{
var test = function(arg)
{
alert(arg);
}
var anotherTest = function(arg)
{
//do something;
}
$('#id').click
(
function(){
var content = "Hello world";
var anchor = "<a href='javascript:void(0);'>test</a>";
$(anchor).click(function(){ test(content); });
$('#DivToBind').prepend(anchor);
});
}
);
Your example is incomplete. The call to bind click is missing a function wrapper (so it's a syntax error and won't even parse); there is no reference to calling anotherText;, and the anchor is never actually created, only a string. So it's not really possible to fix from there.
In general avoid creating dynamic content from HTML strings. As you are not HTML-escaping content, if it contains various special characters (<"'&) your script will fail and you may have a cross-site-scripting security hole. Instead, create the anchor and then write any dynamic attributes or event handlers from script:
$(document).ready(function() {
function test(arg) {
alert(arg);
}
$('#id').click(function() {
var content= 'Hello world';
$('test').click(function(event) {
test(content);
event.preventDefault();
}).appendTo('#somewhere');
});
});
It may be preferable to use a <button> styled like a link rather than a real link, since it doesn't go anywhere. A <span> styled as a link is another possibility, preferably with a tabindex attribute to make it keyboard-accessible in that case.
I think a lot of code is missing here.
But anyway, why won't you use jQuery power to bind events?
$(document).ready(function() {
var test = function(arg) {
alert(arg);
}
var anotherTest = function(arg) {
alert("another: " + arg);
}
$('#id').click(function() {
var content = "Hello world";
var anchor = $("<a href='#'>test</a>").click(function() { test(content); });
//apply anchor to DOM
});
});
I think this is what you're looking for:
$(document).ready(function() {
var test = function(arg) {
alert(arg);
};
var anotherTest = function(arg) {
alert("we did something else:" + arg);
};
$('#id').click(function() {
var content = "Hello world";
var anchor = $("<a>test</a>").click(function(event) {
event.stopPropagation();
// test(content);
anotherTest(content);
});
$('#DivToBind').prepend(anchor);
});
}
);
This example shows good use of event.stopPropagation(). Setting an anchor's href to void() or # is often a mistake.
If you're using jQuery, I would recommend using its event handler functions like so:
$(document).ready(function() {
var test = function(arg){
alert(arg);
}
var anotherTest = function(arg){
// do something;
}
$('#id').click( function(event){
var content = "Hello world";
var anchor = $("<a>test</a>");
anchor.click(function(event){
event.preventDefault(); // instead of javascript:void();
test(content);
});
$('#DivToBind').prepend(anchor);
});
});