Store and access data on server using PHP and AJAX - javascript

I have a website that has the possibility to add comments which are just stored temporarily, when you reload the page the comments are gone. I save the comment data in an ObservAbleArrayList using knockout and javascript. One idea I had was to send this ObservAbleArrayList to my server, store it and then when the page is reloaded the stored arraylist would first update the commentfield. How could I do this with AJAX and PHP?
Here is my javascriptcode for the comments:
function Comment() {
var self = this;
self.nickname = ko.observable();
self.newMsg = ko.observable("");
self.editable = ko.observable(false);
self.addComment = function () {
vm.comments.push(self);
vm.selectedComment(new Comment());
};
self.deleteComment = function () {
vm.comments.remove(self);
};
self.editComment = function () {
self.editable(!self.editable());
};
}
function ViewModel() {
var self = this;
self.comments = ko.observableArray();
self.selectedComment = ko.observable(new Comment());
}
var vm = new ViewModel();
ko.applyBindings(vm);
});
Any help or examples would be very helpful! Thanks in advance.

Send the data as JSON to the server using jQuery as your bridge to handle the server side interaction with it's $.ajax() wrapper.
First, you need to mutate the data into a JSON object to be sent over and easily parsed. In knockout, you can use the .toJSON(model) method on a ko object to get the JSON interpretation of it, such as:
var jsonData = ko.toJSON(ViewModel);
Which will give you your JSON String. This is ready to be passed to the server, so now you can construct your $.ajax() call to your PHP script.
$.ajax({
url: '/path/to/my/script.ext',
type: 'GET', //default anyway, provided for clarity
dataType: 'json', //the returned data from the server will be automatically parsed as json
data: jsonData, //the KO model we converted earlier
success: function(data){
//the server's response is in "data" above, jsonParsed already.
}
});

Related

Knockout JS binnding the ajax result

I am new to Knockout JS, I am trying to bind the ajax result data to Knockout JS viewmodel, but I am facing the problem while binding the data to view, I have create model and viewmodel and I am getting the result from ajax. Need help.
Below is my code:
// ajax on page load///
$.ajax({
type: "POST",
dataType: "json",
url: baseUrl + 'api/xxx/xxx',
data: UserProfileModel,
success: function(data) {
result = data;
////view model////
userDetailsViewModel(result);
},
error: function(error) {
jsonValue = jQuery.parseJSON(error.responseText);
//jError('An error has occurred while saving the new part source: ' + jsonValue, { TimeShown: 3000 });
}
});
//// view model///
var userDetailsViewModel = function(result) {
console.log(result);
self = this;
self.user = ko.observable(new userModel(result));
};
$(document).ready(function() {
ko.applyBindings(userDetailsViewModel());
});
/// Model////
function userModel(result) {
this.name = ko.observable();
this.userName = ko.observable();
}
Your userDetailsViewModel is a function that returns undefined. You'll either have to use new or create a return statement if you want it to create an actual viewmodel. E.g.:
var UserDetailsViewModel = function(result) {
var self = this;
self.user = ko.observable(new UserModel(result));
};
var mainUserDetailsViewModel = new UserDetailsViewModel(data);
You'll have to store a reference if you want to update your viewmodel from the scope of the ajax callback. Alternatively, you could make the ajax functionality part of the viewmodel. The easiest example:
var mainUserDetailsViewModel = new UserDetailsViewModel(data);
$.ajax({
success: function(data) {
mainUserDetailsViewModel.user(new UserModel(data));
}
});
Make sure you use this model in your applyBindings call:
ko.applyBindings(mainUserDetailsViewModel);
Note that I've used CapitalizedNames for functions that need to be instantiated, and uncapitalizedNames for instances of those functions. Following default naming conventions might help keeping track of what's what.

Empty Array AJAX

So I have searched around a bit in hopes of finding a solution to my problem, but have had no luck.
I am basically trying to pass data into the ajax function, but when it passes it to my php file it only returns an empty array (Yes there are a few topics on this, couldn't find any to fit my needs) , here is the console output: Array ()
Its odd because just before the ajax function I log the data, and it prints out each section with no problems.The posting URL is accurate, works fine straight from my form. I have tried to use response instead of data passed through the function, but no luck their either.
Thanks in advance!
Here is the JS file
$(document).ready(function() {
$('form.ajax').on('submit', function() {
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = [];
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
console.log(data); /////THIS LINE HERE ACTUALLY PRINTS DATA
$.ajax({
url: url,
type: type,
data: data,
success: function(data) {
console.log(data);
}
});
return false;
});
});
And here is my PHP
<?php //removed the issets and other checkers for ease of readability
print_r($_POST);
?>
UPDATE: I have tried to add method:"POST" to my ajax function and it still seems to be printing out blank arrays... Maybe I should convert everything to GET?
jQuery ajax() uses GET as default method. You need to mention method: POST for POST requests.
method (default: 'GET')
$.ajax({
url: url,
method: "POST",
type: type,
data: data,
success: function(data) {
console.log(data);
}
});
Or you can also use post().
EUREKA!!! Wow, the mistake was much simpler than I thought, figured it out solo! Thank you everyone for the tips! Finally got it
$('form.ajax').on('submit', function() {
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {}; // THIS NEEDS TO BE CHANGED TO BRACKETS!!

wait for ajax result to bind knockout model

I have getGeneral function that calls ajax GET. When ajax recieves data (json), it creates KO model from given json and returns created KO.
When Knockout model is created and values are assigned, knockout applybindings should be called. Here is my code:
Defines GeneralModel and some related functions (inside "GeneralModel.js"):
var GeneralModel = function() {
//for now it is empty as data ar binded automatically from json
// CountryName is one of the properties that is returned with json
}
function getGeneral(pid) {
$.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: { id: pid},
success: function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
return p;
},
error: function (data) {
}
});
}
This is called from another file (GeneralTabl.html), it should call get function and applyBindings to update UI:
var PortfolioGeneral = getGeneral("#Model.Id");
ko.applyBindings(PortfolioGeneral, document.getElementById("pv-portfolio-general-tab"));
However, in this scenario I am getting error (CountryName is not defined). This is because applyBindings happens before ajax returns data, so I am doing applyBindings to empty model with undefined properties.
Mapping from Json to Model happens here and is assignes values:
p = ko.mapping.fromJS(item);
I can also fill in GeneralModel with all fields, but it is not necessary (I guess):
var GeneralModel = function() {
CountryName = ko.observable();
...
}
It will still give an error "CountryName is not defined".
What is the solution?
1) Can I somehow move getGeneral inside GeneralModel, so get data would be part of GeneralModel initialization?
or
2) Maybe I should somehow do "wait for ajax results" and only then applyBindings?
or
I believe there are other options, I am just not so familiar with KO and pure JS.
Note: I fully understand that this is because Ajax is Async call, so the question is how to restructure this code taking into account that I have two seperate files and I need to call getGeneral from outside and it should return some variable.
Try using the returned promise interface:
function getGeneral(pid) {
return $.ajax({
url: "/api/general",
contentType: "text/json",
dataType: "json",
type: "GET",
data: {
id: pid
}
});
}
getGeneral("#Model.Id").done(function (item) {
var p = new GeneralModel();
p = ko.mapping.fromJS(item);
ko.applyBindings(p, document.getElementById("pv-portfolio-general-tab"));
}).fail(function () {
//handle error here
});

Why does AJAX json script return extra 0 (zero)

I have an AJAX function in WordPress that calls a PHP function to return the value of a transient record in the Database.
When I call the function using jQuery, I receive the result however it always has an extra 0 (zero) appended to the value.
Here is my jQuery function:
(function($) {
$(document).ready( function() {
var AdvancedDashboardWidget = function(element, options)
{
var ele = $(element);
var settings = $.extend({
action: '',
service: '',
countof: '',
query: '',
callback:''
}, options || {});
this.count=0;
var url='';
switch(settings.service)
{
case 'facebook':
if(settings.countof=='likes' || settings.countof=='talks')
{
ajaxCall(action,ele,settings);
}
}
};
var ajaxCall = function(action,ele,settings){
opts = {
url: ajaxurl, // ajaxurl is defined by WordPress and points to /wp-admin/admin-ajax.php
type: 'POST',
async: true,
cache: false,
dataType: 'json',
data:{
action: settings.action // Tell WordPress how to handle this ajax request
},
success:function(response) {
//alert(response);
ele.html(response);
return;
},
error: function(xhr,textStatus,e) { // This can be expanded to provide more information
alert(e);
//alert('There was an error');
return;
}
};
$.ajax(opts);
};
$.fn.advanceddashboardwidget = function(options)
{
return this.each(function()
{
var element = $(this);
// Return early if this element already has a plugin instance
if (element.data('advanceddashboardwidget')) return;
// pass options to plugin constructor
var advanceddashboardwidget = new AdvancedDashboardWidget(this, options);
// Store plugin object in this element's data
element.data('advanceddashboardwidget', advanceddashboardwidget);
});
};
});
})(jQuery);
There are more helper functions involved however this is the main jQuery function that communicates with WordPress and returns the value of the PHP function.
The issue is that if the value is returned as "99" for example it will be returned as "990"
Here is the PHP function that jQuery is calling:
/**
* Get Facebook Likes
*/
public function get_facebook_likes(){
echo 99;
}
If I change the above to return 99; I receive plain 0
Your function should use wp_send_json to encode the PHP as JSON and sent it back to the AJAX request handler. This will also stop executing of any following PHP too, so there is no need to use exit or die.
So for your specific example, you would use:
/**
* Get Facebook Likes
*/
public function get_facebook_likes(){
wp_send_json(99);
}
This is old question but I'm going to answer this. wp_send_json() function may help but not always. There could be some moments when you can't use this function. Like, when you load posts by ajax, you are getting some template part, you can use the function. That's why WordPress documentation suggests to make use of the die() function.
So in the end, your php function should look like this:
/**
* Get Facebook Likes
*/
public function get_facebook_likes() {
echo 99;
die();
}
Use Firebug and view the actual net data transmitted and received. Determine if the error is coming from the javascript side or the PHP side. Copy the net request and paste it into a separate browser window to see the raw result. If it is PHP, pursue that. if it is the javascript doing something, let us know.

Knockout, get JSON from View Model after mapping it

I start with empty view model, then I do an ajax request for data from database. Collected data I mapping using Knockout.Mapping plugin to view model.
Like this:
var myName = new function(){
this.viewModel = {};
var getData = function () {
var mapping = {
'Members': {
create: function (options) {
return new UserMode(options.data);
}
}
}
$.ajax({
url: 'api/board',
data: $.param({"BoardId": 1}),
dataType: 'json',
success: function (data, textStatus, jqXHR) {
this.viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(this.viewModel);
},
});
}
};
Then I opened a JavaScript console in Chrome and typed:
ko.toJSON(myName.viewModel);
And results is
"{}"
I expected to see viewModel with data from server, not empty object.
You made a little confusion, I think you should call applybindings before doing your AJAX loading stuff.
I updated one of my old fiddle to replicate your problem, check it out, hope it will help you!
http://jsfiddle.net/ingro/Buscp/

Categories

Resources