Как заставить мою сетку загрузочных карточек элементов Treeseed 5 отображаться в моем php-файле после вызова базы данныхPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Как заставить мою сетку загрузочных карточек элементов Treeseed 5 отображаться в моем php-файле после вызова базы данных

Сообщение Anonymous »

Я пытаюсь отобразить макет сетки HTML в файле php с именем Gardenshop.php. Внутри контейнера сетки должны находиться элементы сетки в виде карточек Bootstrap 5, которые создаются динамически. Контейнер сетки (a) имеет класс .items-wrapper. Каждая карточка должна состоять из следующего:
a) Контейнер, который относится к классу контейнера mt-3, слайд-контейнера (если на карточке более одного изображения) или контейнера mt-. 3 (если карточка имеет только одно изображение).
b)Div, вложенный в a) с классом древовидной карты
c) В б) вложено изображение или изображения. У меня есть база данных деревьев, и некоторые записи имеют только одно изображение TreeImage1, в то время как другие типы деревьев имеют более одного изображения, причем TreeImage2 и TreeImage3 не равны NULL.
d) Ниже изображений, а также вложенный в b) — это еще один элемент div для cardBody с классом «.card-body».
e)Вложенный в d) должен быть элемент с классом «.card- title», который будет иметь общее имя семени дерева.
f) Вложен в d), но ниже e) должен быть элемент с текстом «Информация:» и иметь класс из ".info-text".
g) Ниже f) и вложенным в d) должен быть неупорядоченный список
  • с элементами списка (поля/столбцы/свойства) для TreeSeeds в виде элементов
  • . У меня есть функция генерацииListItems() в php-файле shopconnect.php, который я импортирую в Gardenshop.php.
    На стороне MySQL я использую Sequelize с таблицей Treeseeds, и она имеет следующие поля:

    id(первичный ключ)
  • commonName DataTypes.STRING (60)
  • speciesName DataTypes.STRING (60)
  • семейство DataTypes.STRING (60)
  • seedcostInclVAT DataTypes.DOUBLE(4,2)< /li>
    quantityInStock DataTypes.INTEGER
  • seedNumberPerPack DataTypes.INTEGER
  • цвет DataTypes.STRING
  • DataTypes выносливости.STRING
  • soilType DataTypes.STRING
  • soilAcidity DataTypes.STRING
  • описание DataTypes.TEXT
  • treeImage1 DataTypes.BLOB
  • treeImage2 DataTypes.BLOB
  • treeImage3 DataTypes.BLOB< /li>
Теперь возвращаясь к g) данные для этих столбцов для каждого семени дерева будут перечислены в списке , о котором я говорил для g), за исключением идентификатора, поскольку пользователю веб-сайта Gardenshop.php не нужно видеть идентификатор записи.
Я использую логику PDO (объект данных PHP) в файле с именем shopconnect.php для подключитесь к моей базе данных и запросите данные обратно с помощью запросов выбора MySQL, как обычно.
//shopconnect.php

Код: Выделить всё

$host = "127.0.0.1";
$db = "database"
$user = "user";
$pass = "password";
$charset = "utf8mb4";

$datasourcestr =  "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES   => false,
];
$pdo = new PDO($datasourcestr, $user, $pass, $options);

$sql1 = "SELECT * FROM suppliers";
$sql2 = "SELECT * FROM treeseeds";

$supplierNameData = $pdo->query($sql1)->fetchAll();
$treeSeedData = $pdo->query($sql2)->fetchAll();

$treeSuppliers = [];

function filterOutSuppliers($parentArr,$childDataArr,$candidateArr){
foreach($parentArr as $parentRow)
{
foreach($childDataArr as $childRow){
if(($parentRow["id"]  $childRow["supplierId"]) === 0 ){
array_push($candidateArr, $parentRow["supplierName"]);
}else{
continue;
}

}
}
return $candidateArr;
}

$treeSuppliers = filterOutSuppliers($supplierNameData,$treeSeedData,$treeSuppliers);

$supplierIds = [];
foreach($supplierNameData as $row1) {
array_push($supplierIds,$row1["id"]);
}

$supplierIdStrs = implode(',', $supplierIds);

$treeSeedQuery = "SELECT * FROM `treeseeds` WHERE supplierId in ($supplierIdStrs)";
$treeSeedDataOut = $pdo->query($treeSeedQuery);

$treeSeedArr = [];

do {
$treeSeedArr = $treeSeedDataOut->fetchAll();
} while ($treeSeedDataOut->nextRowset() && $treeSeedDataOut->columnCount());

$domDoc = new DOMDocument();

function generateTreeCard(){
$topicDiv = $GLOBALS['domDoc']->createElement('div');
$topicDiv->setAttribute('class','tree-card'); //tree-card div is to be appended to the container mt-3
return $topicDiv; //USED IN LOOP BELOW
}

function generateCardBody(){
$cardBody = $GLOBALS['domDoc']->createElement('div');
$cardBody->setAttribute('class','card-body');
return $cardBody;  //DONE ALREADY APPENDED TO TREECARD BELOW IN THE LOOP
}

function addheaderH4Text($value){
$cardTitle = $GLOBALS['domDoc']->createElement('h4',$value);body
$cardTitle->setAttribute('class','card-title');//needs to be appended on to card body
return $cardTitle; //ALREADY DONE IN THE LOOP BELOW
}

function generateListElements($key,$value){
$resultItem = "";
switch($key){
case "commonName":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "speciesName":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "family":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "seedcostInclVAT":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "quantityInStock":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "seedNumberPerPack":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "colour":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "hardiness":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "soilType":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "soilAcidity":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
case "description":
$resultItem = $GLOBALS['domDoc']->createElement('li',"$key : $value");
break;
}
return $resultItem; //needs to be appended to the productInfoList variable [list]
}

$outerContainer = $domDoc->createElement('div');
$outerContainer->setAttribute('class','items-wrapper');

$productInfoList = $domDoc->createElement('ul');
$listElementResult = "";

$imgCollectorArr = [];
$h4Text = "";
$cardBody = "";
$treeCard = "";
$treeImage1 = "";
$infoParagraph = "";
$cardContainer = "";

***ISSUE IS IN THE NESTED FOREACH LOOP HERE ****
foreach($treeSeedArr as $key => $value){
$infoParagraph = generateInfoText(); //Just to display "Information:"
foreach($value as $key1 => $value1){
echo $key1 . " has a value of " . $value1 .  "
";  //***TEST
if($key1 === 'commonName'){
$h4Text = addheaderH4Text($value1); //GENERATE h4 text line'
$cardBody = generateCardBody()->appendChild($h4Text)->appendChild($infoParagraph);
}
if($key1 !== 'id' && $key1 !== 'treeImage1' && $key1 !== 'treeImage2' && $key1 !== 'treeImage3'){
$listElementResult = generateListElements($key1,$value1); // the bullet pointed list of properties
$productInfoList->appendChild($listElementResult);//this is the  tag
}
if($key1 === 'treeImage1' && !(is_null($value["treeImage1"]))){

if(array_key_exists("treeImage2",$value) && !(is_null($value["treeImage2"]))){
$imgCollectorArr["treeImage1"] = $value[$key1];
continue; //if a treeseed has more at least 2 images
}
$treeImage1 = generatetreeImage1($value1); //this is if a treeseed only has one image
$treeCard = generateTreeCard()->appendChild($treeImage1)->appendChild($cardBody);
}

if($key1 === 'treeImage2' && !(is_null($value["treeImage2"]))){
if(array_key_exists("treeImage3",$value) && !(is_null($value["treeImage3"]))){
$imgCollectorArr["treeImage2"] = $value[$key1];
continue; //if a treeseed has 3 images instead of 2
}
//design what happens when there are 2 images
$slideBox1 = $domDoc->createElement('div');
$slideBox1->setAttribute('class','mySlides fade');
$countText1 = $domDoc->createElement('div','1 / 2');
$countText1->setAttribute('class','numbertext');
$slideBox1->appendChild($countText1);
$firstImg = $domDoc->createElement('img');
$firstImg->setAttribute('style','width:100%');
$firstImg->setAttribute('src',$imgCollectorArr["treeImage1"]);
$slideBox1->appendChild($firstImg);

$slideBox2 = $domDoc->createElement('div');
$slideBox2->setAttribute('class','mySlides fade');
$countText2 = $domDoc->createElement('div','2 / 2');
$countText2->setAttribute('class','numbertext');
$slideBox2->appendChild($countText2);
$secondImg = $domDoc->createElement('img');
$secondImg->setAttribute('style','width:100%');
$secondImg->setAttribute('src',"$value1");
$slideBox2->appendChild($secondImg);
$treeCard->appendChild($slideBox1);
$treeCard->appendChild($slideBox2);

//attach on to treecard
$previousLink = $domDoc->createElement('a','❮');
$previousLink->setAttribute('class','prev');
$previousLInk->setAttribute('onclick','plusSlides(-1)');

$forwardLink = $domDoc->createElement('a','❯');
$forwardLink->setAttribute('class','next');
$forwardLInk->setAttribute('onclick','plusSlides(1)');
$treeCard->appendChild($previousLink);
$treeCard->appendChild($forwardLink);

//dots/circles
$dotCircleBox1 = $domDoc->createElement('div');
$dotCircleBox1->setAttribute('style','text-align:center');
$dotSpanA = $domDoc->createElement('span');
$dotSpanA->setAttribute('class','dot');
$dotSpanA->setAttribute('onclick','currentSlide(1)');

$dotSpanB = $domDoc->createElement('span');
$dotSpanB->setAttribute('class','dot');
$dotSpanB->setAttribute('onclick','currentSlide(2)');

$dotCircleBox1->appendChild($dotSpanA);
$dotCircleBox1->appendChild($dotSpanB);
$treeCard->appendChild($dotCircleBox1);
}

if($key1 === 'treeImage3' &&  !(is_null($value[$key1]))){
$slideBoxA = $domDoc->createElement('div');
$slideBoxA->setAttribute('class','mySlides fade');
$countTextA = $domDoc->createElement('div','1 / 3');
$countTextA->setAttribute('class','numbertext');
$slideBox1->appendChild($countTextA);
$firstImg = $domDoc->createElement('img');
$firstImg->setAttribute('style','width:100%');
$firstImg->setAttribute('src',$imgCollectorArr["treeImage1"]);
$slideBoxA->appendChild($firstImg);

$slideBoxB = $domDoc->createElement('div');
$slideBoxB->setAttribute('class','mySlides fade');
$countTextB = $domDoc->createElement('div','2 / 3');
$countTextB->setAttribute('class','numbertext');
$slideBoxB->appendChild($countTextB);
$secondImg = $domDoc->createElement('img');
$secondImg->setAttribute('style','width:100%');
$secondImg->setAttribute('src',$imgCollectorArr["treeImage2"]);
$slideBoxB->appendChild($secondImg);

$slideBoxC = $domDoc->createElement('div');
$slideBoxC->setAttribute('class','mySlides fade');
$countTextC = $domDoc->createElement('div','3 / 3');
$countTextC->setAttribute('class','numbertext');
$slideBoxC->appendChild($countTextB);
$thirdImg = $domDoc->createElement('img');
$thirdImg->setAttribute('style','width:100%');
$thirdImg->setAttribute('src',$value1);
$slideBoxC->appendChild($thirdImg);

$treeCard->appendChild($slideBoxA);
$treeCard->appendChild($slideBoxB);
$treeCard->appendChild($slideBoxC);

$previousLink = $domDoc->createElement('a','❮');
$previousLink->setAttribute('class','prev');
$previousLInk->setAttribute('onclick','plusSlides(-1)');

$forwardLink = $domDoc->createElement('a','❯');
$forwardLink->setAttribute('class','next');
$forwardLInk->setAttribute('onclick','plusSlides(1)');

$treeCard->appendChild($previousLink);
$treeCard->appendChild($forwardLink);

//dots/circles
$dotCircleBox2 = $domDoc->createElement('div');
$dotCircleBox2->setAttribute('style','text-align:center');
$dotSpan1 = $domDoc->createElement('span');
$dotSpan1->setAttribute('class','dot');
$dotSpan1->setAttribute('onclick','currentSlide(1)');

$dotSpan2 = $domDoc->createElement('span');
$dotSpan2->setAttribute('class','dot');
$dotSpan2->setAttribute('onclick','currentSlide(2)');

$dotSpan3 = $domDoc->createElement('span');
$dotSpan3->setAttribute('class','dot');
$dotSpan3->setAttribute('onclick','currentSlide(3)');

$dotCircleBox2->appendChild($dotSpan1);
$dotCircleBox2->appendChild($dotSpan2);
$dotCircleBox2->appendChild($dotSpan3); //FORGOT TO APPEND THESE??
$treeCard->appendChild($dotCircleBox2);

}
}
$cardBody->appendChild($productInfoList);
$treeCard->appendChild($cardBody);
//for the forward and backwards arrow heads
$cardContainer = $domDoc->createElement('div');//needs to be appended to items-wrapper
if(!(is_null($value["treeImage2"])) || !(is_null($value["treeImage3"]))){
$cardContainer->setAttribute('class','container mt-3 slides-container');
}else{
$cardContainer->setAttribute('class','container mt-3');
}

$cardContainer->appendChild($treeCard);
$outerContainer->appendChild($cardContainer);
}
$domDoc->appendChild($outerContainer);
$htmlString = $domDoc->saveHTML();
echo $htmlString;

Итак, из приведенного выше кода я получаю данные обратно из базы данных, но, как я уже говорил ранее, я хочу, чтобы информация была представлена ​​в виде сетки HTML с загрузочными карточками. Проблемы возникают в последней части кода с вложенным циклом foreach (см. звездочки в коде), а также при запуске используемых элементов DOM. По сути, я хочу на каждой итерации проверять, содержит ли запись дерева только одно изображение или несколько. Если семя дерева имеет более одного изображения, я хочу визуализировать карту начальной загрузки 5 со слайд-шоу, где пользователь может щелкнуть точки/круги навигационных стрелок, чтобы увидеть отдельные изображения. //***TEST — это просто оператор echo, проверяющий, возвращаю ли я какие-либо данные.
plusSlides() и currentSlide() — это функции JavaScript в слайдеlogic.js и классах " mySlides Fade» — это классы, которые используются в слайдеlogic.js. См. файл JavaScript ниже.
//slidelogic.js

Код: Выделить всё

let slideIndex  = 1;

showSlides(slideIndex);

//Next/previous controls
function plusSlides(slideNum){
showSlides(slideIndex += slideNum);
}

// Thumbnail image controls
function currentSlide(n) {
showSlides(slideIndex = n);
}

function showSlides(number){
let i;
let slides = document.getElementsByClassName("mySlides");
let dots = document.getElementsByClassName("dot");

if(number > slides.length){
slideIndex = 1;
}

if(number < 1){
slideIndex = slides.length;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";

}

function currentSlide(number){
displaySlides(slideIndex = number)
}

Затем я импортирую приведенный выше файл JavaScript (slidelogic.js) и shopconnect.php в Gardenshop.php
//gardenshop.php

Код: Выделить всё














SPROUTY'S GARDENING SHOP

[url=./homepage.html][i][/i]Back To Homepage[/url]
[*][i][/i]
[/list]





Contains Stainless Steel:&nbsp
FSC (Forest Stewardship Council) certified:&nbsp
In Stock:&nbsp



In Stock:&nbsp
Weight (grams):&nbsp
Price:&nbsp
FSC (Forest Stewardship Council)  certified:&nbsp



In Stock:&nbsp
Litres (Capacity):&nbsp
Price:&nbsp



In Stock:&nbsp
Soil Type:&nbsp
chalk
sand
loam
clay

Soil Acidity:&nbsp
acid
alkaline
neutral

Hardiness:&nbsp
hardy
tender
hardy/half-hardy

Price:&nbsp




In Stock:&nbsp
Is Biodegradable:&nbsp
Litres (Capacity):&nbsp
Price:&nbsp










Наконец-то я услышал CSS от Gardenshop.css
//gardenshop.css

Код: Выделить всё

* {
margin: 0;
padding: 0;
box-sizing: border-box;

}

.mySlides {
display: none;
}

[class~="container mt-3"]{
position: relative;
}

.prev,.next{
transition-duration: 0.6s;
transition-timing-function: ease;
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
}

.next{
right: 0;
border-radius: 3px 0 0 3px;
}

.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}

.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}

.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition-property: background-color;
transition-duration: 0.6s;
transition-timing-function: ease;
}

.active, .dot:hover {
background-color: #717171;
}

@keyframes fade{
from{opacity: 0.4};
to{opacity: 1};
}

.fade {
animation-name: fade;
animation-duration: 1.5s;
animation-direction: normal;
}

/*CSS for the product items dynamically made in PHP (shopconnect.php)*/

.items-wrapper{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
grid-gap: 1rem;
}

Я попробовал свой код, приведенный выше, через XAMMP (рендеринг php-файла Gardenshop.php с использованием Apache)
Я получаю следующий вывод в изображение ниже. Я хотел бы знать, как заставить карты начальной загрузки 5 динамически отображаться в сетке. Динамически в том смысле, что мне не нужно жестко кодировать элементы сетки; если я хочу добавить больше данных о семенах деревьев в свою базу данных, я могу это сделать, а затем, когда веб-страница Gardenshop.php будет загружена (через локальный хост в моем браузере), она автоматически отобразит правильное количество элементов сетки (карточек).
Изображение Gardenshop.php, когда я перехожу на локальный хост и конкретную страницу с помощью XAMPP](https://i.sstatic.net/0bk8E7lC.png)

Подробнее здесь: https://stackoverflow.com/questions/790 ... -my-php-fi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»