How to make this trick with Jquery's each? - php

My php code:
for($i = 1; $i < 22; $i++) {
echo '<div id="number" style="display:none">'.$i.'</div>';
}
My jquery code:
$('#number').each(function() {
$(this).slideDown("slow");
})
What's wrong here? I want to achieve effect when all numbers, each after another would appear. I mean, first of all slides down number 1, after him number 2 and so on. And now only slides down number 1 and after him nothing happens although I use jquery each. Thank you.

There may only be one id="number" in your code. IDs are unique. Use class="number" instead.
That is:
Your PHP-Code:
for ($i = 1; $i < 22; $i++) {
echo '<div class="number" style="display:none">'.$i.'</div>';
}
Your JS-Code:
$('.number').each(function() {
$(this).slideDown("slow");
});

First, your PHP needs a change, it's rendering invalid HTML, so this:
for($i = 1; $i < 22; $i++) {
echo '<div id="number" style="display:none">'.$i.'</div>';
}
Need to be something like this (or remove the id completely if it's not needed):
for($i = 1; $i < 22; $i++) {
echo '<div id="number'.$i.'" class="number" style="display:none">'.$i.'</div>';
}
Then your jQuery should be something like this:
$('.number').each(function(i) {
$(this).delay(600*i).slideDown("slow");
});
You can view a demo here
This will show the first immediately, the second 600ms later (speed "slow" = 600ms), the third after 1200ms, etc, so they'll happen one after the other. All we're doing is using .delay() and passing the index of the element in the set times the animation duration, so they occur in order.

IDs are meant to be unique. Use a CSS class (and corresponding selector ".number") instead.
Once you have them all showing, i'm guessing they'll be showing up all at once. In order to fix that, you'll probably need to create a function that slides in the next number and sets a timeout to call itself again. Like,
function slideNext()
{
$(".number:first").each(function() {
$(this).slideDown("slow").removeClass("number");
window.setTimeout(slideNext, 1000);
});
}
$(document).ready(slideNext);
Note, this is not tested, and i am not by any means a jQuery guru.

You are creating multiple elements with the same id attribute. this is illegal according to the HTML spec and is preventing your jQuery selector from being able to determine which element you are trying to access. Try using a class attribute instead and using $('.number')

You can't have more than one element with the same ID. You need to use a class instead:
PHP
for($i = 1; $i < 22; $i++) {
echo '<div class="number" style="display:none">'.$i.'</div>';
}
Jquery:
$('.number').each(function() {
$(this).slideDown("slow");
})

Use a class instead of an id as id must be unique. I've tried it with class and it worked.
PHP:
for($i = 1; $i < 22; $i++) {
echo '<div class="number" style="display:none">'.$i.'</div>';
}
jQuery:
$('.number').each(function() {
$(this).slideDown("slow");
})
Cool effect! Good luck!

hey - this wouldn't work basically because the id has to be unique, thus the code isn't going to work. it might work if you were to use a class rather than an id (i.e. <div class="number").
haven't tried it - so just a thought really..
jim

It's true that according to spec there is should be only one element with given ID, but you can overcome it by doing:
$( "*[id='number']").each(function() {
$(this).slideDown("slow");
});

hey, for the delay, try this:
$('.number').each(function(i) {
setTimout($(this).slideDown("slow"), i*250);
});
you never know...

Related

How to display foreach loop response during iteration using jQuery or Ajax

is it possible to display foreach loop response during iteration using jQuery or Ajax ?
for($i = 0; $i < 1000; $i ++) {
echo $i;
echo '<br>';
}
I want to call the function using ajax and display $i value in each iteration. Is it possible ?
Like typically, I dont want to wait for full page forloop process end and then echo result.
PS: I am student of Software Engineering in 2nd semester. I am in learning process so please bear me for any foolish request.
Thanks and Regards.

Dynamic PHP website using POST arguments and recursive function

I'm creating a website using PHP for the logic part of it.
It is a dynamic test. A set of questions are presented to the user and depending on his answers, a new set of questions will appear, thus, the questions will always be different if the answers are different.
In the form of the test, I have used POST to get the answers of the user and the action is empty because I want the page to reload but with different arguments (POST) every time. I also use a recursive function that takes the ID's of the next questions to be presented and the level (set of questions) just to not get lost. This recursive function also uses the arguments in POST to, again, obtain the user's answers so it can get the next questions at my DB.
function searchTree($arrNodes, $nivel){
$nxtQ = array(); $j=1;
$arr=getPreguntas($arrNodes,$nivel); //arr has "question" objects
$numPreg=count($arr);
for ($i=0; $i < count($arr); $i++) {
$arrayA[$i] = treeRule($arr[$i]->idPreg); //Array[i] is the set of related rules
}
echo '<form action="" method="post">';
for ($i=0; $i < $numPreg; $i++) {
echo $arr[$i]->pregunta .'</br>';
insertHTML($arr[$i]->idPreg, $numPreg, $j, $nivel); //Add HTML
$j++;
}
echo '</br><input type="submit" id="buttonSend'.$nivel.'" name="buttonSend'.$nivel.'" value="Enviar respuesta">';
echo '</form>';
$button= 'buttonSend'.$nivel;
if(isset($_POST[$button])){ //If the user answered
for ($i=0; $i < count($arrayA); $i++) { //arrayA has all related rules
if(!empty($arrayA[$i])){ //At least one related rule
$radio = 'valorRadio'.($i+1).'_'.$nivel;
$node = 'idNode'.($i+1).'_'.$nivel;
$answ[$i] = analize($_POST[$radio],$_POST[$node],$arrayA[$i],$i+1, $nivel); //$answ is the set of related rules which happened to be true
if($answ[$i]!=null){
echo 'True related rule: '.$answ[$i].' </br> ';
}else{
echo 'Answer all questions';
}
}else{ //End of analysis
echo 'No related rules </br>';
}
}
$relatedMR = getmetaRules($arrayA);
for ($i=0, $j=0; $i < count($relatedMR); $i++) {
$res = analizeMR($relatedMR[$i], $arrayA);
if($res=='1'){
$nxtQ[$j] = getNxtQ($relatedMR[$i]); //nxtQ is the set of next questions' IDs
$j++;
}
}
if($nxtQ!=NULL){
$_POST=array();
$arrNodes = array();
searchTree($nxtQ,($nivel+1));
}else{
echo 'End of test';
}
}else{
time_sleep_until($_POST);//Wait for an answer
}
}
I call this function at the beginning of my program like this:
searchTree(initialNodes(1),1);
initialNodes() function only enters the DB and gets the questions with level 1.
The first and second set of questions are presented (kind of) correctly (the first set of questions is always present and the second one appears under it, but that can be fixed at front-end.), however, the third one if not working anymore. The POST arguments are there but the new questions and radio buttons do not appear.
First set and POSTFirst and second set and POSTThird attempt and POST
I created an easier example of this by not using "sets of questions" but only one question each time. The first and second questions work as I previously mentioned but for the third one, the second one is replaced by the third and the third by the fourth and so on.
I don't know if my program is getting confused by the names of my HTML elements, if my recursive function is wrong or something else.

While echo - dont write mutiple lines, overwrite one instead

im trying to write a loop that displays the counter on one line, been sitting here for over an hour but cant figure it out.
The main loop is
while($counter< 100){
echo $counter;
usleep($timeInSeconds*1000000);
$counter=$counter+1;
}
Now this prints 100 numbers after a delay each on a new line. Is it possible for the echo to instead replace itself for each loop?
I tried many options, here is one that didnt crash:
while($counter < 100){
$counter=$counter+1;
echo $counter;
usleep($timeInSeconds*1000000);
flush();
ob_flush();
}
However, with this option it works in one line with a delay, but it doesnt clear the previous echo, so its just a bunch of number next to each other
Could someone help me out?
You are trying to do something on the server that should be done on the client.
I expect you are making a timer. You should write some JavaScript code instructing the web browser on how to display multiple numbers with a delay in between. Your current code will show a loading wheel and a blank screen for the entire duration on many browsers.
Instead, replace your loop with something like:
var time_in_seconds = 1; // You can replace 1 with the value of the PHP variable
var count_element = document.getElementById("example_counter");
var n = 0;
var interval_id;
function update_counter(){
n += 1;
if (n >= 100) {
clearInterval(interval_id);
}
count_element.textContent = n;
}
interval_id = setInterval(update_counter, time_in_seconds * 1000);
<span id="example_counter"></span>

php script optimisation

I'm not a php guru, need your help.
I have a php form with select menu. The menu is formed form the customers table e-mails. I've used the following code:
for($i = 0; $i < sizeof($customers_table); $i++){
echo '<option value="'.$customers_table[$i]['id'].'">'.$customers_table[$i]['email'].'</option>';
}
The base is rather big, so it takes time to form the option field. Is there any way to optimize the script so it will work faster.
Thank you.
As the size does not change, store it:
$size = sizeof($customers_table);
for ($i = 0; $i < $size; $i++) {
echo '<option value="'.$customers_table[$i]['id'].'">'.$customers_table[$i]['email'].'</option>';
}
Then you can shorten the loop condition and reduce the array access:
$i = $size = sizeof($customers_table);
while ($i) {
$table = $customers_table[$size-$i--];
echo '<option value="'.$table['id'].'">'.$table['email'].'</option>';
}
Next part is the echo statement which can just output instead of concatinating strings before outputting them:
$i = $size = sizeof($customers_table);
while ($i) {
$table = $customers_table[$size-$i--];
echo '<option value="', $table['id'], '">', $table['email'], '</option>';
}
If this makes a difference, you need to metric. The largest time taken might be the amount of HTML you send to the browser. But that would be out of the scope of this fragment.
To improve the overall readability of the code I suggest using foreach:
foreach ($customer_table as $row)
{
echo '<option value="', $table['id'], '">', $table['email'], '</option>';
}
This generally is pretty fast as well.
As Andy said, it's not a good idea to optimize this script that way.
If you want significant time changes, you have to rethink the problem.
You have a list of customers, and if there is a problem of time, I assume that there are a lot. So, a drop-down list would be useless for a user.
There are other solutions, more efficient :
Using a sort of caching > Your html code will always be the same, so you just need to do the loop once, when you add, delete or update a customer, and store the html code in a script or database. So, each time your page is reloaded, you just have to retrieve the html code.
Do not load all the customers > The user doesn't need to see all the customers, just the ones he's interested in, so with some Ajax you can load the options while the user is typing (see this for example: jQuery Autocomplete)
Those solutions are the best for optimization, and if you combine them (caching and autocomplete above 3 characters typed) it will be even better for user experience too.

Using javascript to loop dynamically created controls with php

Ok, this situation is a little weird but anyway. This PHP code generates several radiobuttons:
for($i = 0; $i<count($questionList); $i++)
{
echo $questionList[$i]->__get(QuestionId).'-'.$questionList[$i]->__get(QuestionText).'<br />';
$answerList = $questionList[$i]->GetAnswers();
for($j = 0; $j<count($answerList); $j++)
{
echo '<br /><input type=\'radio\' name=\'group'.$i.'\' id=\'radioButtonAnswer'.$answerList[$j]->__get(AnswerId).'\' value=\''.$answerList[$j]->__get(AnswerId).'\' >'.
$answerList[$j]->__get(AnswerText).'</input>';
}
echo '<br /><br />';
}
Ok, that works fine, after the checkboxes are created, I'm trying to run some code to get all the radio buttons and it didn't work, so I tried just getting one radio button several times, and it only gets it the first time.
function Validate()
{
var i = 1;
do
{
document.writeln(document.getElementById('radioButtonAnswer2') == null);
i ++;
}while(i < 10);
document.writeln('out of loop');
return false;
}
So I know FOR SURE that 'radioButtonAnswer2' exists and it shouldn't be null. But this is what I get when I click the submit button:
false true true true true true true true true out of loop
The first time is not null, but after that, it is. Any thoughts?
Thanks!
You can use document.getElementsByName("group") to get all the radio buttons.
This loop works fine. The problems is with document.writeln(), it replaces the html in the page and therefore the DOM elements are gone. Here's an updated version using an Alert instead.
function Validate(){
var radioGroup = document.getElementsByName("group");
var results = "";
for(i = 0, len = radioGroup.length; i < len; i++){
currentRadio = radioGroup[i];
results += "\n" + currentRadio.id + " is ";
results += (currentRadio.checked ? "checked" : "not checked");
}
results += "\n..out of loop...";
alert(results);
return false;
}
It may be because your HTML you are generating is invalid. You also shouldn't be explicitly calling the __get() function, but that's an unrelated issue most likely.
Something like:
<input type="radio" ...>Label Text</input>
is not the correct way to define a radio button.
Try this code:
for($j = 0; $j<count($answerList); $j++)
{
echo '<br /><input type="radio" name="group'.$i.'" id="radioButtonAnswer'.$answerList[$j]->AnswerId.'" value="'.$answerList[$j]->AnswerId.'" />';
echo '<label for="radioButtonAnswer'.$answerList[$j]->AnswerId.'">'.$answerList[$j]->AnswerText.'</label>';
}
Edited to add: Ah, now I see. You're using document.writeln(). That function overwrites the content of the page.
So the first time into the loop, the element does exist, and it does a document.writeln() call, which writes "true" to the page. This overwrites everything that was on the page before (didn't you notice how when the page loads, it only has the output of the javascript?). The next time through the loop, it tries to look for the radio button again, but it's been erased and replaced with the javascript output. Now it no longer exists.

Categories