skip to Main Content

I am not sure if there is an answer to my question or if it even possible but here goes:

I am working on an old Codeigniter 3.1.9 site in PHP 8.2.12. My question is is it possible to have search result from a database be split up into smaller pieces to be placed in separate divs for legibility or would I be confined to using table tds?

At present, the search on the site searches a database that contains a "recipe" table and that table has 14 fields and contains 58 records. I am only trying to request 5 of those fields per search. The issue right now is that as it stands, I am only able to get a recipe name and link to it. I have categories and subcategories for each recipe listed but I don’t like the idea of having that all be crammed into a single div or even a single column. Is there any way I can rectify this?

I am still new to PHP and this project was dumped in my lap to figure out and trying to decipher this monster of a site has been quite the challenge. I have kept it running since Codeigniter 1.83. Please be kind as I navigate my way through this.

Also I didn’t initially write the code for this site so I am having to reverse engineer nearly everything. I will provide any files you might need to see. I just don’t want to make my post any longer than it already is and overwhelm you all with needless code.

Recipe.php Controller

function search(){
   if($this->input->method() === 'post'){
    $search = $this->input->post('query');  
    $results = $this->recipe_model->search($search);
    $data = array(
     'title' => "Shirley's Recipes:Search Results", 
     'columns' => array('toc', 'public/page/search_results'), 
     'recipes' => $results  
    );
    $this->load->view('templates/main', $data);
   }
   else{ 
    redirect('recipe');
   }
  } 

Recipe_model

function search($search){
 $terms = explode(' ', $search);    
 $match = " ";   
 foreach($terms as $term){    
  $match .= $term;
 }
   
 $querystr = "SELECT *, MATCH(name, category, subcategory, keywords) AGAINST('".$match."') as score  FROM recipe WHERE MATCH(name, category, subcategory, keywords) AGAINST('".$match."') ORDER BY score DESC;";
   $q = $this->db->query($querystr);
   return $q->result();
  }

search_results.php

<link rel="stylesheet" type="text/css" href="/assets/css/public/page/searchresults.css" media="screen" />
<div id="sitecontent" class="grid-item2 grid-container">
  <?php
   if($admin){
    $this->load->view('admin/nav/notesnav');
   }
  ?>
  <div id="contents" class="grid-item1 grid-container scrollbar <?php if($admin){echo 'grid-item2';} ?>">
   <div id="spiral" class="grid-item1">
    <img class="spiral" src="/assets/img/lines/spiral1trans.png"/>
   </div> 
   <div id="searchresults" class="grid-item2 grid-container">
    <h1>Search Results</h1>
    <div id="results" class="grid-item1 grid-container">
     <div id="resultsheading" class="grid-item1 heading">Your Results:</div>
     <div id="numheading" class="grid-item2 heading">#:</div>
     <div id="resultlistheading" class="grid-item3 heading">Results:</div>
     <div id="categoryheading" class="grid-item4 heading">Category:</div>
     <div id="subcategoryheading" class="grid-item5 heading">Subcategory</div>
     <div id="num1" class="grid-item6">1</div>
      <div id="result1" class="grid-item7">
       <ol>
       <?php     
         if(!empty($recipes)): 
         foreach($recipes as $recipe): 
        ?>
        <li><a href="/recipe/<?= $recipe->id ?>"><?=$recipe->name ?></a></li>       
        <?php endforeach; ?>
       </ol> 
       <?php else: ?>
       No matching recipes
       <?php endif; ?>
      </div>
      <div id="category1" class="grid-item8"></div>
      <div id="subcategory1" class="grid-item9"></div>
      <div id="num2" class="grid-item10">2</div>
      <div id="result2" class="grid-item11">
       
      </div>
      <div id="category2" class="grid-item12"></div>
      <div id="subcategory2" class="grid-item13"></div>
      <div id="num3" class="grid-item14">3</div>
      <div id="result3" class="grid-item15">Eventually I will have each result appear on its own line.</div>
      <div id="category3" class="grid-item16"></div>
      <div id="subcategory3" class="grid-item17"></div>
      <div id="num4" class="grid-item18">4</div>
      <div id="result4" class="grid-item19">Eventually I will have each result appear on its own line.</div>
      <div id="category4" class="grid-item20"></div>
      <div id="subcategory4" class="grid-item21"></div>
      <div id="num5" class="grid-item22">5</div>
      <div id="result5" class="grid-item23">Eventually I will have each result appear on its own line.</div>
      <div id="category5" class="grid-item24"></div>
      <div id="subcategory5" class="grid-item25"></div>
       <div id="num6" class="grid-item26">6</div>
      <div id="result6" class="grid-item27">Eventually I will have each result appear on its own line.</div>
      <div id="category6" class="grid-item28"></div>
      <div id="subcategory6" class="grid-item29"></div>
       <div id="num7" class="grid-item30">7</div>
      <div id="result7" class="grid-item31">Eventually I will have each result appear on its own line.</div>
      <div id="category7" class="grid-item32"></div>
      <div id="subcategory7" class="grid-item33"></div>
       <div id="num8" class="grid-item34">8</div>
      <div id="result8" class="grid-item35">Eventually I will have each result appear on its own line.</div>
      <div id="category8" class="grid-item36"></div>
      <div id="subcategory8" class="grid-item37"></div>
       <div id="num9" class="grid-item38">9</div>
      <div id="result9" class="grid-item39">Eventually I will have each result appear on its own line.</div>
      <div id="category9" class="grid-item40"></div>
      <div id="subcategory9" class="grid-item41"></div>
       <div id="num10" class="grid-item42">10</div>
      <div id="result10" class="grid-item43">Eventually I will have each result appear on its own line.</div>
      <div id="category10" class="grid-item44"></div>
      <div id="subcategory10" class="grid-item45"></div>      
    </div>
    </div>
   </div>
   <div id="updated" class="grid-item2">Updated 05/27/2023 @ 2:34 EDT</div>
  </div>    

Thank you all for any help you can offer.

2

Answers


  1. Yes this is entirely possible, firstly debug the $results as you will find it should contain all the columns you need.

    You can then edit the template according to what you are doing, change it to div’s in the foreach if you like. Currently you are using li’s.

    I would suggest a table since they are easier to work with and organise a set of data, however you might consider using div’s with display:flex or something, thats up to you.

    Login or Signup to reply.
  2. I’ve looked up your site via Google, so I think I understand what you’re trying to do. Your current layout uses display:grid with grid-template-areas in css so that’s why you’re using all the numbered ids and classes in html. If you want to keep the numbered ids and classes, you can change your code like this:

      <div id="results" class="grid-item1 grid-container">
        <div id="resultsheading" class="grid-item1 heading">Your Results:</div>
    
        <div id="numheading" class="grid-item2 heading">#:</div>
        <div id="resultlistheading" class="grid-item3 heading">Results:</div>
        <div id="categoryheading" class="grid-item4 heading">Category:</div>
        <div id="subcategoryheading" class="grid-item5 heading">Subcategory</div>
    
        <?php
        if (!empty($recipes)):
          $itemNumber = 6;
          foreach ($recipes as $key => $recipe):
            $rowNumber = $key + 1;
        ?>
            <div id="num<?= $rowNumber ?>" class="grid-item<?= $itemNumber++ ?>"><?= $rowNumber ?></div>
            <div id="result<?= $rowNumber ?>" class="grid-item<?= $itemNumber++ ?>">
              <a href="/recipe/<?= $recipe->id ?>"><?= $recipe->name ?></a>
            </div>
            <div id="category<?= $rowNumber ?>" class="grid-item<?= $itemNumber++ ?>"><?= $recipe->category ?></div>
            <div id="subcategory<?= $rowNumber ?>" class="grid-item<?= $itemNumber++ ?>"><?= $recipe->subcategory ?></div>
          <?php endforeach; ?>
        <?php else: ?>
          <div style="grid-column: 1 / -1" class="heading">No matching recipes</div>
        <?php endif; ?>
    
      </div>
    

    I’ve moved the foreach loop so it surrounds the 4 divs that hold the data for one recipe,
    and moved the if/else around that.

    Then added an $itemNumber variable that starts at 6 (because your first recipe num div has the grid-item6 class), this is then used to print the numbers in all grid-item# classes. (<?= $itemNumber++; ?> prints the $itemNumber and then increases its value by one.)

    I’ve also added a $rowNumber variable for the numbering of the ids and the value of the num div,
    this is based on the $key in the recipes array (this is numbered starting at 0).

    If no recipes are found, a div is displayed that spans the entire width of the grid (style="grid-column: 1 / -1"). I gave it the heading class to give it some styling, but you might want to change that.


    You do however have a lot of duplicate code in your css for the numbered ids and classes, so I would suggest changing your html to this instead:

      <div id="results" class="grid-item1 grid-container">
        <div id="resultsheading" class="grid-item1 heading">Your Results:</div>
    
        <div id="numheading" class="grid-item2 heading">#:</div>
        <div id="resultlistheading" class="grid-item3 heading">Results:</div>
        <div id="categoryheading" class="grid-item4 heading">Category:</div>
        <div id="subcategoryheading" class="grid-item5 heading">Subcategory</div>
    
        <?php
        if (!empty($recipes)):
          foreach ($recipes as $key => $recipe):
        ?>
            <div class="grid-item num"><?= $key + 1 ?></div>
            <div class="grid-item result">
              <a href="/recipe/<?= $recipe->id ?>"><?= $recipe->name ?></a>
            </div>
            <div class="grid-item category"><?= $recipe->category ?></div>
            <div class="grid-item subcategory"><?= $recipe->subcategory ?></div>
          <?php endforeach; ?>
        <?php else: ?>
          <div class="grid-item no-result">No matching recipes</div>
        <?php endif; ?>
    
      </div>
    

    This gives each num div a num class, each result div a result class, each category div a category class and each subcategory div a subcategory class. I’ve added a no-result class to the "No matching recipes" div and all divs also get the grid-item class for shared styling.

    Then change the css for the grid-container to remove the fixed number of rows for the recipes:

    #results.grid-container{
     display:grid;
     grid-template-columns:2% 32.6% 32.6% 31.9%;
     grid-template-rows:repeat(2, 25px);
     grid-auto-rows: 24px; 
     grid-template-areas:
     'resultsheading resultsheading resultsheading resultsheading'
     'numheading resultlistheading categoryheading subcategoryheading';  
     grid-gap:4px;         
     padding:4px;
     margin:0;       
    }
    

    The styling for the num, result, category and subcategory classes can then be shortened to this (there’s still duplication here, but I’ve left it like this because it was separate in the original as well):

    /* ~~~~~~~~> RESULTS COMMON NUM DIV STYLES <~~~~~~~~ */
    #results .num {
     /* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#91b3e5+0,6890cb+44,91b3e5+100;Blue+3D+%2314 */
     background: #91b3e5; /* Old browsers */
     background: -moz-linear-gradient(top,  #91b3e5 0%, #6890cb 44%, #91b3e5 100%); /* FF3.6-15 */
     background: -webkit-linear-gradient(top,  #91b3e5 0%,#6890cb 44%,#91b3e5 100%); /* Chrome10-25,Safari5.1-6 */
     background: linear-gradient(to bottom,  #91b3e5 0%,#6890cb 44%,#91b3e5 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#91b3e5', endColorstr='#91b3e5',GradientType=0 ); /* IE6-9 */
     font-weight:bold; 
     text-align:center;
     color:navy; 
     padding:2px;        
     border:1px solid blue;
     border-radius:4px;        
    }
    /* ~~~~~~~~> RESULTS COMMON RESULT DIV STYLES <~~~~~~~~ */
    #results .result{ 
     background-image:url("/assets/img/backgroundimg/southworth-blue.jpg");        
     text-align:left;
     color:navy;   
     padding:2px;            
     border:1px solid blue; 
     border-radius:4px;        
    }
    
    /* ~~~~~~~~> RESULTS COMMON CATEGORY DIV STYLES <~~~~~~~~ */
    #results .category{
     background-image:url("/assets/img/backgroundimg/southworth-blue.jpg");        
     text-align:left;
     color:navy;   
     padding:2px;            
     border:1px solid blue; 
     border-radius:4px;        
    }
    
    /*~~~~~~~~> RESULTS COMMON SUBCATEGORY DIV STYLES <~~~~~~~~ */
    #results .subcategory{
     background-image:url("/assets/img/backgroundimg/southworth-blue.jpg");        
     text-align:left;
     color:navy;   
     padding:2px;            
     border:1px solid blue; 
     border-radius:4px;        
    }
    

    To add the alternate row colors back in:

    /* background color for "odd" rows */
    #results .grid-item:nth-child(8n + 7),
    #results .grid-item:nth-child(8n + 8),
    #results .grid-item:nth-child(8n + 9){
     background:#91b3e5;       
    }
    /* background color for "even" rows */
    #results .grid-item:nth-child(8n + 11),
    #results .grid-item:nth-child(8n + 12),
    #results .grid-item:nth-child(8n + 13){
     background:#6890CB;   
    }
    

    And styling for the "No matching recipes" div:

    #results .no-result{
     grid-column: 1 / -1;
     background:#91b3e5;       
     text-align:center;
     color:navy; 
     padding:2px;        
     border:1px solid blue;
     border-radius:4px;        
    }
    

    Made a fiddle here: https://jsfiddle.net/8aLupgjt/

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search