Jump to content

Trying to create progress bars for Processwire generated cards.


spercy16
 Share

Recommended Posts

I was hoping to be able to do this entirely in PHP but was having all kind of issues getting it to see my values as numbers instead of strings (got error messages because my PW debugging is currently set to true). I currently have about 10 cards that PW is generating that include thumbnails, descriptions, donation amounts (raised amounts and goal amounts), and donate buttons. What I was trying to do was take the goal amount divide it by the raised amount (using PHP) and simply insert that value into the Progress element's Value attribute. Sounded simple enough but I couldn't get PHP to simply divide those two fields. First I tried dividing the goal value by the raised value and inserting it into the value attribute, like so:

<? php
$raised = $page->get("raisedAmount$count");
$goal = $page->get("goalAmount$count");
$percent = $goalNum / $raisedNum;
?>

<progress value="<?php echo $percent; ?>" max="100"></progress>

Which gave me this error message:

Uncaught TypeError: Unsupported operand types: string / string

Then I tried converting the two strings to integers because apparently PHP couldn't detect they were numbers and do it, like so:

<?php
$raised = $page->get("raisedAmount$count");

$goal = $page->get("goalAmount$count");

$goalNum = (int) $goal;
$raisedNum = (int) $raised;

if ($raisedNum != 0) :
	$percent = $goalNum / $raisedNum;
else:
	$percent = 0;
endif;
?>

<progress value="<?php echo $percent; ?>" max="100"></progress>

but all of the progress bars remain at zero percent (not shown), even when I have values in some of the $raised variables.

Please note, if I add this code:

<?php echo $percent; ?>

below the Progress element, it shows 0 on every single card, so the $percent is never calculated (as per the $percent = $goalNum / $raisedNum;) even though $raisedNum should not equal 0 during that iteration of the loop (the original code includes a loop, which I omitted to keep the code sections above smaller, notice the $count at the end of the $raised and $goal variable declarations). When the loop goes over "raisedAmount1" there is a value in there; however, after typecasting it to an integer ($raisedNum) the value is 0 for someodd reason instead of 40,000, which is what is in the $raisedAmount1 field in Processwire...

I'm new to relatively new to PHP and Processwire and could really use some help on this one. Thanks in advance for any helpful replies!

Link to comment
Share on other sites

What are raisedAmount$count and goalAmount$count you’re getting with $page->get? Fields that contain a dollar sign? Or is $count supposed to be a subfield of raisedAmount/goalAmount ? I’ve never seen a construction like that with dollar signs in, usually you do $page->field or $page->get('field') and field names cannot contain dollar signs, as far as I know. So what are the results of those two get calls if any and what are their types when you ask for gettype($goal) or gettype($goalNum)?

 

Link to comment
Share on other sites

Hello Spercy16,

Firstly I don't think it is good practice (or possibility at all) to use dollar sign in fields name - raisedAmount$count - really bad practice to my opinion. Continue using camelCase style or add underscore - raisedAmountCount or raisedAmount_count. 

First error: In your first example - you are calling variables $goalNum and $raiseNum without declaring them at all. That is why these variables are empty. 

Second problem: raisedAmount$count and goalAmount$count are fields or pages? Get rid of dollar sign in field name and use direct aproach for calling fields in this scenario. $page->raisedAmountCount etc. (page->get documentation). 

Also do not typecast these variables in your code. If this field should contain only integer values than change field type in processwire to Integer. 

Really your main problem are fields you are calling raisedAmount$count. Is this the field name? Or is it child page with another field $count? Maybe give us more information about your field and page structure to tell you right way to call these fields. 

<? php

$raised = $page->raisedAmountCount; //if these fields are integer type
$goal = $page->goalAmountCount;

$percent = $goal / $raised; // You will change this, because you are calling not existing vars
?>

<progress value="<?php echo $percent; ?>" max="100"></progress> <!-- This should be working without any problems -->

 

Link to comment
Share on other sites

Cehlo,

Firstly, in PHP you do not have to declare variables before assigning values to them... In other languages like C, C++, and Java you do, but not PHP.

Second, I have used raisedAmount$count and goalAmount$count in other places and they work correctly. $count is another variable that starts with 0 and increments each iteration through the loop (outputting my cards, as mentioned). Here is the full code:

<?php
    // https://processwire.com/api/arrays/
    // check if the array of images has items
    if (count($page->images)) :

     // get array of images from the field
     $images = $page->images;

     $count = 0;

     // iterate over each one
     foreach ($images as $image) :

      $count++;

      $sectionText = $page->get("paragraph_$count");

      $buttonCode = $page->get("url_$count");

      $options = array( 'quality' => 70 );

      $img = $image->size(550, 400, $options);

      $raised = $page->get("raisedAmount$count");

      $goal = $page->get("goalAmount$count");

      $goalNum = (int) $goal;
      $raisedNum = (int) $raised;

      if ($raisedNum !== 0) :
       $percent = $goalNum / $raisedNum;
      else:
       $percent = 0;
      endif;

    ?>

<span id="card<?php echo $count?>" class="card">

  <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" />

  <div class="cardBody">

    <div class="cardText">
      <h2><?php echo $image->description; ?></h2>
      <?php echo $sectionText; ?>
    </div>

    <div class="progressBarSection">
      <progress class="progressBar" id="progressbar<?php echo $count; ?>" value="<?php echo $percent; ?>" max="100"></progress>
      <span class="raisedAmount">
        <?php echo $raised; ?> ksh
      </span>
      <span class="goalAmount">
        <?php echo $goal; ?> ksh <?php echo $percent; ?>
      </span>
      <span id="raisedNum<?php echo $count?>" class="hidden">
        <?php echo $raised; ?>
      </span>
      <span id="goalNum<?php echo $count?>" class="hidden">
        <?php echo $goal; ?>
      </span>
    </div>

    <div class="primaryBtn">
      <a href="https://www.paypal.com/donate?hosted_button_id=
               <?php echo $buttonCode; ?>
               &source=url">
        <button>
          <i class="fas fa-donate"></i> Donate
        </button>
      </a>
    </div>

  </div>

</span>

<?php
     endforeach;
     endif;
    ?>

Sorry, should have just included this in the original post. It makes a lot more sense when you can see the whole structure of the cards.

As you can see I'm using $count successfully in the $sectionText and $buttonCode variables (paragraph_$count and url_$count respectively). I've been using the variables this way in PHP for a while and have had zero issues thus far. Also, when I echo $goal and $raised in the span elements in my html they display the correct values. The current problem I'm experiencing isn't with using $count when declaring variables, it's when trying to typecast the values into integers directly below that.

You suggested to use $page->raisedAmountCount to call fields, but you need to understand that by using $count here you are able to use a loop so that each time through it uses the next value (i.e. it's really grabbing $page->raisedAmount1, $page->raisedAmount2, etc. each run through it). I have numerous raisedAmount fields in my page (1-15) and listing them out individually would be incredibly inefficient. This is what i++ was created for, one of the several reasons anyways... If there is a more proper way to write that code and get the same results, efficiently, I'm all ears, but the way I am using those variables is working in all of the other declarations I've used them in, and from what I do understand about programming is exactly how you should use variables like that.

Hopefully the full code will help make what I'm trying to do a bit easier to understand.

Link to comment
Share on other sites

Ah, okay, I see. It was a bit confusing without knowing the context. But what values/types exactly do you get after typecasting $goal and $raised? Did you try intval($val) instead of (int) $val?

Link to comment
Share on other sites

You still didn’t reveal your results. Could you do something like that to see the four values and their according types?

$raised = $page->get("raisedAmount$count");
$goal = $page->get("goalAmount$count");
$goalNum = (int) $goal;
$raisedNum = (int) $raised;

echo $raised;
echo gettype($raised);
echo $goal;
echo gettype($goal);
echo $goalNum;
echo gettype($goalNum);
echo $raisedNum;
echo gettype($raisedNum);

Normally it shouldn't be much of a problem to divide two integers in PHP, so I suspect it to be slightly more hidden.

Link to comment
Share on other sites

Now it is a lot clearer. Yes you are right in both points. Either way from your first post it was not certain. 

Regarding variables you are right, but in your first post your first php input was using variables without giving them value. So $percent = $goalNum / $raisedNum; will give you everytime 0, becasue variables $goalNum and $raisedNum are empty. But I can see from your next post that you are giving them values so it was just misunderstanding. 

If count is another variable it is also without problems from your full code, consider my first post as irrelevant then.  i

Ok and what about your fields? Are they Integer or Text fields? Can you change them and avoid typecasting at all?

 

 

 

Link to comment
Share on other sites

Cehlo,

Bypassing typecasting worked. I had to create all new fields in ProcessWire (kind of a pain that I couldn't simply change the types from text to integers...) but now everything works. Thanks for all of your help!

Link to comment
Share on other sites

2 minutes ago, cehlo said:

I am happy it worked 🙂

I am happy too! Though I don't understand why the typecasting didn’t work, (int) "40000" (or intval("40000")) should result in 40000, not 0. Strange …

Link to comment
Share on other sites

As far as I know in PHP a quotient of integers with a non-integer value is treated as float.

So I'd try to cast the $percent value:  

$percent = (int) $percent;

or

$percent = intval($goalNum / $raisedNum);

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...