I am using immediately invoked functions pattern, but this is not passing the id
1.When the user clicks on $user, id is passed and the chat window appears
echo "<div class='boxbottom'><a href='#' onclick=chat_com_one($id);> >$user</a><br></div>";
2.Function chatcom_load_one keep checking, if there is any message from the id passed to chatcom_load_one function.
But the problem is that onclick function do passes the id but immediately invoked function did not pass the id to the post function.
Also sending the message is slow?
Please help or suggest any alternate approach, I think error is in the chat_load_one pattern.
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#chatcom #commid #commidwin').html(data);
setTimeout(chatcom_load_one(id), 1000);
});
}());
$('#chatcom_send').click(function () {
var text = document.getElementById('chatcom_text').value;
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
}, f
function (data) {
document.getElementById('chatcom_text').value = '';
});
});
}
send function on my server
if($_REQUEST['option']=='chat_com_send_one'){
$session=new $session;
$text=mysqli_real_escape_string($db3->connection,$_POST['text']);
$tocom=mysqli_real_escape_string($db3->connection,$_POST['tocom']);
$sql=mysqli_query($db3->connection,"INSERT INTO chat_com(fro,tocom,mesg,time) VALUES ('$session->userid','$tocom','$text',CURRENT_TIMESTAMP)");
}
First off, I notice two problems:
You have a syntax error in the parameter list to $.post
You probably don't want to do this: setTimeout(chatcom_load_one(id), 1000);
Here's an updated version of your code with these errors fixed:
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#chatcom #commid #commidwin').html(data);
setTimeout(function () {
chatcom_load_one(id);
}, 1000);
});
}());
$('#chatcom_send').click(function () {
var text = document.getElementById('chatcom_text').value;
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
},
function (data) {
document.getElementById('chatcom_text').value = '';
});
});
}
Also, since you're using jQuery, you can simplify document.getElementById.... Another updated version (with some more changes to make it more readable):
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#commidwin').html(data);
setTimeout(function () {
chatcom_load_one(id);
}, 1000);
});
}(id));
$('#chatcom_send').click(function () {
var text = $('#chatcom_text').val();
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
},
function (data) {
$('#chatcom_text').val('');
});
});
}
These are just a few cleanups, there may be others.
Edit:
Added devnull69's insight to my final updated code. Hopefully it's useful (accept his answer if this was the problem).
Edit: Other notes
Why are you doing $.post in chatcom_load_one? It would make much more sense as a $.get, and the query parameters would still be sent. It's not really a problem per se, but it's bad style. This should probably be in a file called getchat.php or something instead of doing what I expect is looking for the text parameter.
Also, I don't know the implementation of sendchat2.php, but you should probably reduce the timeout. Try something like 250ms or so. That's not going to overload the server and it'll improve response time.
In addition to the previously mentioned problems you invoke the immediately executed function without any parameter. You will have to add the (id) parameter to the function call in order to hand over the id element to its local copy inside the function.
(function chatcom_load_one(id) {
...
}(id));
Related
I'm working on a song site, where you can rate songs, singers etc, and you also have the option to add them to your favourites.
After a while I've noticed when I add/remove song/singer from my favourites, I pretty much repeate the same ajax request multiple times, only with a different feedback message, so I decided to create a separate function of that request, and in other methods I just call this.
For this I set things such as the route of the button, feedback, message etc in the parameter of the favourite function, as you can see below.
The feedback() function is not really important I believe, I just shared if someone would like to know how it looks like, or if they'd actually find it important anyway.
function feedback($feedback_route,$message_route,$alert_class,$message){
$($feedback_route).removeClass("d-none");
$($feedback_route).addClass($alert_class);
$($feedback_route).addClass("animated fadeIn");
$($message_route).html($message);
setTimeout(() => {
$($feedback_route).addClass("animated fadeOut");
}, 2000);
setTimeout(() => {
$($feedback_route).addClass("d-none");
$($feedback_route).removeClass($alert_class);
$($message_route).html("");
}, 2500);
}
function favourite($ajax_route,$post,$button_route,$event,$feedback_route,
$message_route,$success_message,$error_message){
$.ajax({
url: $ajax_route,
type: "post",
data: {
$post: $($button_route).attr("value"),
event:$event
},
success: (data) => {
feedback($feedback_route,$message_route,"alert-success",$success_message);
setTimeout(() => {
$($button_route).replaceWith(data);
}, 2500);
},
error: () => {
feedback($feedback_route,$message_route,"alert-danger",$error_message);
}
});
}
//-------------------------------ADD SONG TO FAVOURITES-----------------------------
$("#song-info-container #song-container").on("click","#add-to-favourites", () => {
favourite(
"ajax/song-favourite.php",
"songID","#song-info-container #song-container #add-to-favourites",
"add","#song-info-container #song-container .feedback",
"#song-info-container #song-container #message",
"Added!","Failed to add!"
);
$("#song-info-container #song-container .feedback").removeClass("animated fadeOut");
});
Here's how the original ajax request looks like:
$("#song-info-container #song-container").on("click","#add-to-favourites", () => {
$.ajax({
url: "ajax/song-favourite.php",
type: "post",
data: {
songID: $("#song-info-container #song-container #add-to-favourites").attr("value"),
event:"add"
},
success: (data) => {
feedback("#song-info-container #song-container .feedback",
"#song-info-container #song-container #message","alert-success","Added!");
setTimeout(() => {
$("#song-info-container #song-container #add-to-favourites").replaceWith(data);
}, 2500);
},
error: () => {
feedback("#song-info-container #song-container .feedback",
"#song-info-container #song-container #message","alert-danger","Failed to add!");
}
});
$("#song-info-container #song-container .feedback").removeClass("animated fadeOut");
});
And now the actual problem: first I thought it actually works, because the feedback appears with the correct message, but after it disappears(see in the setTimeOut function), the following message appears:
Notice: Undefined index: songID in G:\x\htdocs\AniSong\ajax\song-favourite.php on line 9
So the data which is also set in the parameter of the favourite function is not being passed to the other file.
Does someone know why this happens?
Or can I not do an ajax request like this in the first place?
PS: Sorry if the title doesn't make sense, didn't really know how it should be asked.
This doesn't do what you're expecting:
{
$post: $($button_route).attr("value"),
event: $event
}
This won't replace $post with the string value you're passing to the function. This gives the property the literal name $post. Check the network tab of your browser's debugging tools to see what you're actually sending to the server. There is no songID property.
A quick test to validate:
let $foo = 'test';
console.log({$foo: 'baz'});
If you want to dynamically send this information, you'll need to modify your data structure to do that. Similar to how you have a dynamic "event", you'll now need a dynamic "post". Something like:
{
post: $post,
value: $($button_route).attr("value"),
event: $event
}
Then in your server-side code you'd change your logic to examine the post parameter to see what field you're updating, or whatever such logic you're using server-side.
Alternatively, it just occurs to me that you could potentially create a dynamic property name. Consider something like this:
let $post = 'songID';
let data = {
event: 'add'
};
data[$post] = 'test value';
console.log(data);
It's up to you which you think is more complex vs. which is easier for you to support.
Hello all and thanks in advance,
Short story, I am using a plugin to dynamically populate select options and am trying to do it via an ajax call but am struggling with getting the data into the select as the select gets created before the ajax can finish.
First, I have a plugin that sets up different selects. The options input can accept an array or object and creates the <option> html for the select. The createModal code is also setup to process a function supplied for the options input. Example below;
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
let dueDate = {};
for (let i = 1; i < 32; i++) {
dueDate[i] = i;
}
return dueDate;
}
}
});
What I am trying to do is provide an object to the options input via AJAX. I have a plugin called postFind which coordinates the ajax call. Items such as database, collection, etc. are passed to the ajax call. Functions that should be executed post the ajax call are pass through using the onSuccess option.
(function ($) {
$.extend({
postFind: function () {
var options = $.extend(true, {
onSuccess: function () {}
}, arguments[0] || {});
options.data['action'] = 'find';
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof options.onSuccess === 'function') {
options.onSuccess.call(this, obj);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
}
});
}(jQuery));
The plugin works fine as when I look at the output it is the data I expect. Below is an example of the initial attempt.
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
$.postFind({
data: {
database: 'dashboard',
collections: {
accountTypes: {
where: {status: true}
}
}
},
onSuccess: function (options) {
let dataArray = {};
$.each(options, function (key, val) {
dataArray[val._id.$oid] = val.type;
});
return dataArray;
}
})
}
}
});
In differnt iterations of attempting things I have been able to get the data back to the options but still not as a in the select.
After doing some poking around it looks like the createModal script in executing and creating the select before the AJAX call can return options. In looking at things it appears I need some sort of promise of sorts that returns the options but (1) I am not sure what that looks like and (2) I am not sure where the promise goes (in the plugin, in the createModal, etc.)
Any help you can provide would be great!
Update: Small mistake when posted, need to pass the results back to the original call: options.onSuccess.call(this, obj);
I believe to use variables inside your success callback they have to be defined properties inside your ajax call. Then to access the properties use this inside the callback. Like:
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
myOptions: options,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof this.myOptions.onSuccess === 'function') {
this.myOptions.onSuccess.call(this);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
It's not clear to me where the problem is without access to a functional example. I would start with a simplified version of what you want to do that demonstrates the proper functionality. My guess is the callbacks aren't setup exactly correctly; I would want to see the network call stack before making a more definitive statement. A few well-placed console.log() statements would probably give you a better idea of how the code is executing.
I wrote and tested the following code that removes most of the complexity from your snippets. It works by populating the select element on page load.
The HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<select data-src='test.php' data-id='id' data-name='name'></select>
</body>
</html>
<html>
<script>
$('select[data-src]').each(function() {
var $select = $(this);
$select.append('<option></option>');
$.ajax({
url: $select.attr('data-src'),
data: {'v0': 'Alligator', 'v1': 'Crocodile'}
}).then(function(options) {
options.map(function(option) {
var $option = $('<option>');
$option
.val (option[$select.attr('data-id')])
.text(option[$select.attr('data-name')]);
$select.append($option);
});
});
});
</script>
And the PHP file:
<?php
header("Content-Type: application/json; charset=UTF-8");
echo json_encode([
[ 'id' => 0, 'name' => 'Test User 0' ],
[ 'id' => 3, 'name' => $_GET['v0'] ],
[ 'id' => 4, 'name' => $_GET['v1'] ]
]);
Here's a fiddle that also demonstrates the behavior.
Here is my function to get the data requested from a remote server. All is fine but one thing.
function get_users_request()
{
var result = [];
var idx=0;
$.get("getUsers_actions.php",
function(data) {
for (var key in data)
{
result[idx++]=data[key];
console.log(data[key].login);
}
},
"json");
return result;
}
The output is:
hissou
hbadri
user_1
But when i try to get get_users_request() result an empty array is given [].
Since it's an asynchronous call, you need to make use of a callback when you call the function:
function get_users_request(callback)
{
$.get("getUsers_actions.php", callback,"json");
}
get_user_request(function(data){
//var result = [];
//var idx=0;
//for (var key in data)
//{
// result[idx++]=data[key];
// console.log(data[key].login);
//}
$.each(data, function(k, v){
console.log(v.login);
});
});
To understand the code above, you could simulate an ajax call using a timeout:
var myAjaxResult;
setTimeout(function(){
myAjaxResult = 1; // try to update the value
}, 1000 /* simulates a 1 second ajax call */);
console.log(myAjaxResult); //undefined
Since console.log(myAjaxResult); isn't wrapped in a callback, it will be called immediately, and thus still be undefined.
If we would have waited for at least one second, the value would be set. But instead of presuming a time when the call is completed, we can make a callback function and know exactly when its done:
function myFunc(callback){
setTimeout(function(){
callback(1 /* returns the value 1 to the callback */);
}, 1000 /* simulates a 1 second ajax call */);
}
myFunc(function(callbackData){ //call the function using
//the callback we just specified
console.log(callbackData);
});
Hope this helps! Just let me know if anything is unclear.
This is what can give the result.
function get_users_request(s)
{
var s =new Array(), idx=0;
$.ajax({
url: "getUsers_actions.php",
success: function(data){
$.each(data, function(k, v){
s[idx++] = v.login;
console.log(v.login);
})
},
dataType: "json"
});
console.log(s);
}
You should put return result; after the for loop. The return should be done AFTER the $.get call is finished. Where is it now, the return is accessed right after the $.get call STARTS
I'm having trouble implementing autocomplete in jqgrid. I've walked researching, alias until I based this question on a site that currently do not meet. The problem is this, I have to use the autocomplete several times throughout the application I'm developing. And now I have this function:
Javascript:
function autocomplete_element(value, options) {
var $ac = $('<input type="text"/>');
$ac.val(value);
$ac.autocomplete({
source: function(request, response)
{
$.getJSON("autocomplete.php?id=estrategico",
{ q: request.term }, response);
}
});
return $ac;
}
Jqgrid:
jQuery("#obj_oper_org").jqGrid({
(...)
{name:'COD_OBJ_EST',index:'COD_OBJ_EST', hidden: true, editable:true, editrules:{required:true, edithidden:true}, edittype : 'custom', editoptions : {'custom_element' : autocomplete_element}},
What was intended to pass a parameter to the javascript function more in order not to repeat forever the same function for each field because I need to be constantly changing url. Is it possible to make something of the genre? Sorry for the question but I do not have much experience in javascript, so I have some difficulties
First of all you don't need to use edittype : 'custom' to be able to use jQuery UI Autocomplete. Instead of that you can use just dataInit.
You can define myAutocomplete function for example like
function myAutocomplete(elem, url) {
setTimeout(function () {
$(elem).autocomplete({
source: url,
minLength: 2,
select: function (event, ui) {
$(elem).val(ui.item.value);
$(elem).trigger('change');
}
});
}, 50);
}
and then use
{ name:'COD_OBJ_EST', hidden: true, editable: true,
editoptions: {
dataInit: function (elem) {
myAutocomplete(elem, "autocomplete.php?id=estrategico");
}
}}
Be careful that the name of parameter which will be send to the server is the standard name term instead of the name q which you currently use. I personally don't see any need to change the default name of the parameter.
Im currently new to PHP and JQuery after having using ASP.Net and C Sharp for the 2 years. I have this major problem in which i require some assistance in.
I have a HTML <input type="submit" id="btnWL" value="Add to Wishlist"> button. Basically when this button is pressed a table called 'wishlist' in the database is checked to see if the current product is already in a wishlist. If no the button will trigger a database save else it will return a JQuery alert pop up error message.
I having difficulty in passing 2 PHP variables: $_SESSION["username"] and $_GET["ProductId"] into this JQuery method:
<script type="text/javascript">
$(document).ready(function() {
$('#btnWL').live('click', function() {
$.post("addToWishlist.php");
});
});
</script>
As you can see this JQuery method must pass those values to an external PHP File which checks for an already exsisting record in the 'wishist' table with those details.
<?php
$WishlistDAL = new WishlistDAL();
$result = $WishlistDAL->get_ProductInWishlistById($_GET["ProductId"]);
if (isset($_POST["isPostBack"])) {
if (isset($_SESSION["username"])) {
if (isset($_GET["btnWL"])) {
//Check if ProductId is in Cart
if (mssql_num_rows($result)>0)
{
//Return an error
//Sumhow this has to trigger an alert box in the above JQuery method
}
else
{
//Write in Wishlist Table
$WishlistDAL->insert_ProductInWishlist($_GET["ProductId"], $_SESSION["username"]);
}
}
}
else
{
//Return Error
}
}
?>
Another problem I have is then displaying an alert box using the same JQuery method for any errors that where generated in the php file.
Any Ideas how I can implement this logic? Thanks in advance.
Your "$.post()" call isn't passing any parameters, and has no callback for interpreting the results:
$.post('addToWishlist.php', { username: something, password: something }, function (response) {
});
The "something" and "something" would probably come from your input fields, so:
$.post('addToWishlist.php', { username: $('#username').val(), password: $('#password').val() }, function (response) {
});
Now the callback function would interpret the response from the server:
$.post('addToWishlist.php', { username: $('#username').val(), password: $('#password').val() }, function (response) {
if (response === "FAIL") {
alert("fail");
}
else {
// ... whatever ...
}
});
Exactly what that does depends on your server code; that "FAIL" response is something I just made up as an example of course.
jQuery accepts an callback:
$(document).ready(function() {
$('#btnWL').live('click', function() {
$.post("addToWishlist.php", {'isPostBack':1}, function(res){
if (res.match(/err/i)){
alert(res);
}
});
});
});
Then, in the php, just (echo('Error adding record')) for this jquery to see there's an error string in the response and pop up the error message.
Other methods would be to use json, or http status codes and $.ajaxError(function(){ alert('error adding'); });.
from what i can tell so far is you'll only need to pass in the product id in and you can do this by appending your $.post call with the value; this will pass to your php script as a query string variable. i'm not sure which php script you posted, but if you're sending your data with jquery, it's using post and not get, so you may need to make an adjustment there and the session data should be available regardless, since it's the same session.
again this is without seeing all the code and since some of it isn't labeled, it's hard to determine. another thing, i like to use $.ajax for most actions like this, you have a lot more room to define and structure, as well as create one generic ajax function to call the methods and post data, as well as make a response callback. here's the documentation for you to look into $.ajax
i hope this helps.