i have an ajax call and it works good , when i call a new ajax call inside the old one , i got error in the first call
just one ajax call
$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE",function(data){
var concepts = data[0];
var relations = data[1];
for(var i = 0 ; i < concepts.length ; i++){
var IOS = '';
$("#ioAddRelatedConcepts").append('<p>\n\
connect to\n\
<span class="ioAddConcept">'+concepts[i]+'</span>\n\
with\n\
<span class="ioAddRelation">'+relations[i]+'</span>\n\
<select name ="concetedIOs[]" class="TypeSelector">\n\
'+IOS+'</select>\n\
<span class="errorMessage"></span>\n\
remove\n\
</p>\n\
<p>');
}
});
after adding this ajax call
$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE",function(data){
var concepts = data[0];
var relations = data[1];
for(var i = 0 ; i < concepts.length ; i++){
$.getJSON("http://localhost/Mar7ba/InformationObject/getIOsForConcept/"+concepts[i]+"/TRUE",function(data1){
var IOS = '';
$("#ioAddRelatedConcepts").append('<p>\n\
connect to\n\
<span class="ioAddConcept">'+concepts[i]+'</span>\n\
with\n\
<span class="ioAddRelation">'+relations[i]+'</span>\n\
<select name ="concetedIOs[]" class="TypeSelector">\n\
'+IOS+'</select>\n\
<span class="errorMessage"></span>\n\
remove\n\
</p>\n\
<p>');
});
}
});
after that , the concepts[i] and the relations[i] will be as undifined
and the data1.length always null
and the this is the second php code for ajax
public function getIOsForConcept($conceptName, $AJAX) {
if ($AJAX) {
$results = $this->model->getIOsForConcept($conceptName);
$IOs = array();
$i = 0;
while ($row = $results->fetch()) {
$IOs[$i] = $row['name'];
$i++;
}
return json_encode($IOs);
}
}
and i tried it and it works good
You can't use a loop variable ( i in your case) inside a callback function - it'll have whatever value it had when the loop terminated by the time your async callback function is invoked.
As you're already using jQuery, you might as well use $.each():
$.getJSON(..., function(data) {
var concepts = data[0];
var relations = data[1];
$.each(concepts, function(i, value) {
// concepts[i] is OK to use now, and is also in "value"
// relations[i] is OK to use too
$.getJSON(..., function() {
// you can still use them here, too!
});
});
});
which will ensure that i is correctly bound to the current iteration number each time.
The reason that concepts[i] and the relations[i] are undefined within the callback function of the inner $.getJSON() function is that $.getJSON() is aysnchronous which means that the entire for loop will have finished running before any of the callbacks occur on the inner $.getJSON() calls - so by the time these inner callbacks occur i is one higher than the maximum index of the concepts and relations arrays.
To get around this you can introduce an extra closure to keep the values from each iteration:
$.getJSON("http://localhost/Mar7ba/Ontology/getRelatedConceptsAndRelations/"+conceptName+"/TRUE", function(data){
var concepts = data[0];
var relations = data[1];
for(var i = 0 ; i < concepts.length ; i++){
(function(currentConcept, currentRelation) {
$.getJSON("http://localhost/Mar7ba/InformationObject/getIOsForConcept/"+currentConcept+"/TRUE" , function(data1){
var IOS = '';
$("#ioAddRelatedConcepts").append('<p>\n\
connect to\n\
<span class="ioAddConcept">'+ currentConcept +'</span>\n\
with\n\
<span class="ioAddRelation">'+ currentRelation +'</span>\n\
<select name ="concetedIOs[]" class="TypeSelector">\n\
'+IOS+'</select>\n\
<span class="errorMessage"></span>\n\
remove\n\
</p>\n\
<p>');
});
})(concepts[i], relations[i]);
}
});
The anonymous function I've added inside the for loop will run once per iteration creating separate closures each with their own currentConcept and currentRelation.
EDIT: To make it really obvious what I've changed compared to your original code--
Add the following line as the first thing inside your existing for loop:
(function(currentConcept, currentRelation) {
And then the following line as the last thing before your existing for loop's closing }:
})(concepts[i], relations[i]);
And then everywhere inside the for loop where you did have concepts[i] and relations[i] change them to currentConcept and currentRelation.
Related
I am getting the data from the sql table and storing the results inside the associative array after that i have encoded into json but the problem is that it is returning the html of the page along with the results
this is my php code
<?php
add_action('wp_ajax_nopriv_my_loadmore','my_loadmore');
add_action('wp_ajax_my_loadmore','my_loadmore');
function my_loadmore(){
global $wpdb;
$table_name="wpnn_tweets";
$paged=$_POST['page'];
$page=$paged*10;
$results = $wpdb->get_results("SELECT * FROM $table_name LIMIT 1 OFFSET $page");
$arr = array();
foreach($results as $row){
$arr['userScreen']=$row->userScreen;
$arr['userName']=$row->userName;
$arr['tweetCreated']=$row->tweetCreated;
$arr['tweetText']=$row->tweetText;
$arr['tweetRetweetCt']=$row->tweetRetweetCt;
$arr['tweetFavoriteCt']=$row->tweetFavoriteCt;
}
echo json_encode($arr);
wp_die();
}
?>
this is how i am retrieving the json in the front end
$ = jQuery;
function scroller() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
$(this).off("scroll.ajax");
var page=parseInt($(this).data('page'));
var ajaxurl=$(this).data('url');
$.ajax({
url:ajaxurl,
type:"POST",
data:{
page:page,
action:"my_loadmore"
},
error:function(response){
console.log("error");
},
success:function(data){
for(i = 0; i < data.length; i++) {
console.log(data[i]);
}
}
});
}
}
$(window).on("scroll.ajax", scroller);
var ajaxurl = $(this).data('url');
This returns null unless you explicitly set it in your HTML. The easiest solution is to replace it with something like the following.
var ajaxurl = 'my-cool-endpoint';
This was not the solution to this particular problem, but I feel like it's a good thing to check for others coming to this page with the same problem. Replace wp_die() with die(). See the documentation for more details, but here is the relevant line.
A call to this function complements the die() PHP function. The difference is that HTML will be displayed to the user in the case of a typical web request.
I can't push the value of my array to my php file.
Script:
<script>
$(document).ready(function() {
var item_code = [];
$('#save').click(function() {
var item_name = [];
var item_value = [];
var item_quantity = [];
for (var i = 0; i < item_code.length; i++) {
item_code.push($(this).val());
}
$('.item_name').each(function() {
item_name.push($(this).val());
});
$('.item_value').each(function() {
item_value.push($(this).val());
});
$('.item_quantity').each(function() {
item_quantity.push($(this).val());
});
$.ajax({
url: "insert2.php",
method: "POST",
data: {
item_name: item_name,
item_code: item_code,
item_value: item_value,
item_quantity: item_quantity,
},
success: function(data) {
}
});
</script>
I have a value storing at "item_code" whenever I search the item code on my search bar. And after that, I want to push the value of item_code[] on the insert2.php.
I'm not getting any error, but the system itself is frozen.
I am guessing that "item_code" variable is also declared globally somewhere else in your code, otherwise there would be no point in iterating through it. Try using a different name instead of "item_code" to send it to "insert2.php".
for (var i = 0; i < item_code.length; i++) {
item_code.push($(this).val());
}
You can't push data into the same array that you are looping because you will never reach the end of it, unless the memory limit will tell you otherwise. Declare "item_code_second" and push into that:
$(document).ready(function() {
var item_code_second = [];
and change your loop:
for (var i = 0; i < item_code.length; i++) {
item_code_second.push($(this).val());
}
also you are pushing the same value "$(this).val()" as many times as there are values in item_code, which is not making any sense and the exact same value in name, quantity and value. $(this) represents the button that was pushed, don't forget you are in an on click event.
Using jQuery load html forms dynamically using append function. Here the following code load the page content dynamically based on number times of values on while loop.
Here I have a struggle on load the content with different values.its working with single value of 0 or 1 on var load_with_value=0; but not on both simultaneously i.e. increment the load_with_value++ for again load the page content of HTML forms.
$(document).ready(function(e) {
$("<DIV>").load("<?php echo $url; ?>", function() //url for loading page
{
var n = $('.item').length + 1; //load the html page content
var i = 1; //iteration for number of times load the content
var count = 2; //check the condition
var load_with_value = 0; //load the page content with different values for display different values on html form
while(i<count) { //loop starts
$("#product").append($(this).html());
i++;
load_with_value++;
}
});
});
First of all let's do some proper code formatting and get rid of the incorrect comments:
$(document).ready(function(e) {
$("<DIV>").load("<?php echo $url; ?>", function() {
var n = $('.item').length + 1;
var i = 1;
var count = 2;
var load_with_value = 0;
while(i<count) {
$("#product").append($(this).html());
i++;
load_with_value++;
}
});
});
Now let's take it apart:
If you want to use a temporary element to store the loaded data you need to assign it to a variable, so instead of
$("<DIV>").load("<?php echo $url; ?>", function() {
do
var tempObject = $("<div/>").load("<?php echo $url; ?>", function() {
Afterwards you can append the temporary element to an existing one with $('#someExistingElement').append(tempObject).
If you want to load the content into an existing element you should use it's ID, class or other selector to do this - not $("<div>").. If you want to load it to all div elements (please don't) then it should be $("div").
Next var n = $('.item').length + 1; makes no sense. It is never used in the code.
While cycle in this case is unnecessary. Don't use while cycles if you don't have to. You can use:
for(var i=0; i<count; i++){
//code
}
What is var load_with_value = 0; used for? I can only see you incrementing it with load_with_value++; but you don't use it anywhere..
Finally if you want to load different content based on the incremented variable it should be done outside of the .load function.. For example
$(document).ready(function(){
for(var i=0; i<5; i++){
$('#container-' + i).load('/somecontent-' + i + '.html');
}
});
This loads the content /somecontent-0.html to /somecontent-4.html into container elements with IDs container-0 to container-4 respectively.
Let's say I have this PHP variables :
$SelectedCountry = "USA";
$SelectedState = "Texas";
on the other hand, I have this javascript function to display all available countries and states :
function print_country(country_id){
// given the id of the <select> tag as function argument, it inserts <option> tags
var option_str = document.getElementById(country_id);
option_str.length=0;
option_str.options[0] = new Option('Where do you live now?','');
option_str.selectedIndex = 0;
for (var i=0; i<country_arr.length; i++) {
option_str.options[option_str.length] = new Option(country_arr[i],country_arr[i]);
}
}
function print_state(state_id, state_index){
var option_str = document.getElementById(state_id);
option_str.length=0; // Fixed by Julian Woods
option_str.options[0] = new Option('Select state','');
option_str.selectedIndex = 0;
var state_arr = s_a[state_index].split("|");
for (var i=0; i<state_arr.length; i++) {
option_str.options[option_str.length] = new Option(state_arr[i],state_arr[i]);
}
}
my question is... how to make 'USA' and 'Texas' becomes selected <option> which generated by those two javascript functions? thanks.
NOTE #1 : you can see the complete code of javascript here : http://sourceforge.net/projects/countries/files/
NOTE #2 : those function called by adding this line on my PHP :
<script type="text/javascript" src="scripts/countries.js"></script>
<script language="javascript">print_country("country");</script>
so basically I need your help how to pass that PHP variables so that it can be 'received' by javascript function INSIDE that countries.js file.
One way is to just echo out some JavaScript statements:
<script>
<?php
echo "
var SelectedCountry = '$SelectedCountry';
var SelectedState = '$SelectedState';
";
?>
</script>
Then just use them in your loops to check if the option needs to be selected or not.
If you're going to be doing a lot of this sort of thing, though, embedding PHP into JavaScript isn't really the best approach. Read up on AJAX and PHP's json_encode() function.
There are two answers:
1 Use AJAX cal and pass back JSON
$.ajax({
url: '/myScript.php',
success: function(data) {
//Do something
}
});
myScript.php
return json_encode($myVar);
2 Embed PHP into the JavaScript
<script>
var myPHPVariable = <?php echo $myVar; ?>
</script>
Here is a part of my view(a javascript method that is executed on a button click):
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
var moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
var editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
var jEditors = str3.split(',');
}
Here is the controller method i need to call using the 3 arrays from the javascript(moderators, editors,jEditors):
function insertPos($moderators,$editors,$jEditors){
$account = new Account();
$account->insertPos($moderators,$editors,$jEditors);
}
I need to know how to execute the controller method insertPos($moderators,$editors,$jEditors) using the 3 arrays in the javascript method...
I used this to send the arrays in the javascript like you told me:
$.post('http://localhost/cakephp/Accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in the controller i try to access my arrays like this:
public function insertPos() {
if (!empty($this->request->data)){
print_r($this->request->data);
$moderators = $this->request->data['moderators'];
$editors = $this->request->data['editors'];
$jEditors = $this->request->data['jEditors'];
$account = new Account();
$account->assignPos($moderators,$editors,$jEditors);
}
}
the part inside the if(!empty($this->request->data)) is never executed so that means the arrays have not been sent to the controller.... where is the problem?
thank you....
It looks like you're trying to access a controller class directly. This is not how CakePHP works. You have to go through the dispatch process. Please read: http://book.cakephp.org/2.0/en/getting-started/a-typical-cakephp-request.html
That said, the way you would POST to a CakePHP url is thusly:
// POST to the AccountsController's insertPos method
$.post('/accounts/insertPos');
To pass data, pass it in the data option as specified with jQuery, prefixed with 'data', like data[moderators] so it ends up in Cake's data variable.
$.post('/accounts/insertPos', {
data: {
'data[moderators]': moderators,
'data[editors]': editors,
'data[jEditors]': jEditors
}
});
The data will now end up in $this->request->data in Cake.
Looking at your insertPost() method, though, you are passing them simply as parameters, so instead you would write your ajax like so
// POST is unnecessary here, since you aren't POSTing data
$.get('/accounts/insertPos/'+moderators+'/'+editors+'/'+jEditors);
You will probably need to stringify your JavaScript arrays and use json_decode in your inserPos method to convert them to PHP objects, since you can't just pass arrays from JavaScript to PHP.
don't use array notation in data parameter; just use keys like this:
$.post('/accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in your controller access it as $this->request->data[key] not $this->request->data->data[key]
in the view replace your assign function with the following:
var moderators, editors, jEditors;
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
jEditors = str3.split(',');
}
Good luck