Dropdown nested categories with unlimited subcategories -> Ajax / Laravel - php

Im trying to create Nested Dropdown categories using the following code:
My DB-> Table product_categories with fields:
-id
-categoryName
-parentId-level
-is_active
My Product Entity to retrieve categories:
public function getAjaxGetCategoriesDropdown() {
$categories = DB::table('product_categories')
->where('is_active', 1)
->orderBy('path', 'asc')
->select('categoryName','level','id','parentId')
->get();
$first = array();
$children = array();
foreach ($categories as $cat) {
if ($cat->level == 2) {
$first[$cat->id] = $cat;
} else if ($cat->parentId) {
$children[$cat->parentId][] = $cat;
}
}
return array('first' => $first, 'children' => $children);
}
Controller:
public function create()
{
$cats = $this->product->getAjaxGetCategoriesDropdown();
return View('products/create_product')->with(compact('products','cats'));
}
In View: (create.blade.php)
<div class="section">
<label class="field select">
<select id="first_cat" class="required-entry validate-select" onchange="showCat(this, 2)">
<option value=""> Select a Category </option>
<?php foreach ($tree['first'] as $cat): ?>
<option value="<?php echo $cat->id ?>"><?php echo $cat->categoryName ?></option>
<?php endforeach ?>
</select>
<i class="arrow double"></i>
</label>
<div id="sub_cat"></div>
</div>
My Script:
<script type="text/javascript">
var children = $H(<?php echo json_encode($tree['children']) ?>);
function showCat(obj, level) {
var catId = obj.value;
level += 1;
if ($('cat_container_' + level)) {
$('cat_container_' + level).remove();
}
if (children.get(catId)) {
var options = children.get(catId);
var html = '<select id="cat_' + catId + '" onchange="showCat(this, ' + level + ')">' + '<option value="">Select a SubCategory</option>';
for (var i = 0; i < options.length; i++) {
html += '<option value="' + options[i].entity_id + '">' + options[i].name + '</option>';
}
html += '</select>' + '<i class="arrow double"></i>';
html = '<label class="field select ' + 'cat_container_' + level + '">' + html + '</label>';
$('sub_cat').insert(html);
}
}
</script>
The current error that the Log displays says:
Undefined Variable Tree in create.blade.php
.. code <?php foreach ($tree['first'] as $cat): ?>
I've been using this code with success on a Magento app, but now porting the same approach to Laravel is not showing results. Any help appreciated.

Change
foreach($tree ...
To
foreach($cats ...
In your view file.

Related

Uncaught Error: Call to a member function get_results() on null even if $wpdb already declared

I've recently just started doing projects in Wordpress, specifically with plugins. So, I have a dynamic dependent dropdown that uses AJAX that I want to show in an admin plugin menu where I am using $wpdb object for the queries. The problem is using get_results() for my query results in a "Call to a member get_results() on null" even though I already declared global $wpdb.
I've tried adding
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-load.php');
on my AJAX url location, it didn't work.
index.php
//For enqueuing script
function data_capture_tool_filter() {
wp_enqueue_script('ajax-filter', plugins_url('/js/ajax-script.js',__FILE__), array('jquery'), '1.0.0', true);
}
ajax-script.js
jQuery(document).ready(function() {
$('#cluster').on('change', function() {
var cluster_id = $(this).val();
if (cluster_id) {
$.ajax({
type: 'POST',
url: 'https://localhost/csccrc/wp-content/plugins/wp-csc-crc/pages/ajax_test.php',
data: 'id=' + cluster_id,
success: function(html) {
$('#issue').html(html);
}
});
}
alert(cluster_id);
});
});
ajax_test.php
<?php
global $wpdb;
?>
<?php
if (isset($_POST["id"]) && !empty($_POST["id"])) {
//Get all state data
$query = $wpdb->get_results("SELECT * FROM wp_issues");
echo $query;
//Count total number of rows
$rowCount = $query->num_rows;
//Display states list
if($rowCount > 0){
echo '<option value="">Select issue</option>';
foreach ($query as $row) {
echo '<option value="'.$row->id.'">'.$row->name.'</option>';
}
} else {
echo '<option value="">Issue not available</option>';
}
}
?>
Data Capture Tool Page
<form action="#" method="post">
<div class="container">
<!-- Thematic Clusters dropdown -->
<div class="col-md-8">
<select id="cluster" name="cluster">
<option value="">Thematic Clusters</option>
<?php foreach ($clusters as $cluster) : ?>
<?= '<option value="' . $cluster->id . '">' . $cluster->name . '</option>' ?>
<?php endforeach; ?>
</select>
</div>
<!-- Issues dropdown -->
<div class="col-md-8">
<select id="issue" name="issue">
<option value="">Issues</option>
</select>
</div>
<!-- Articles dropdown -->
<div class="col-md-8">
<select id="article" name="article">
<option value="">Articles</option>
<?php foreach ($articles as $article) : ?>
<?= '<option value="' . $article->id . '">' . $article->title . '</option>' ?>
<?php endforeach; ?>
</select>
</div>
</div>
<input type="submit" value="Filter">
</form>

How to make custom search & filter page in wordpress?

I want to make custom search page where I can filter results as shown in the screenshot below:
Currently my problem is that all the items of the list are coming in a single category while I want a grouped view according to different categories e.g. "Device Features", "Mobile Phone Operating System", etc. So far I've written below piece of PHP code:
<?php
$listCategories = get_categories();
if(isset($listCategories) && !empty($listCategories)){
?>
<div class="list-section">
<h3 class="list-heading">Topics</h3>
<ul id="post-grid">
<?php
foreach($listCategories as $categories){
$total_post = get_posts(array('post_type'=>'post', 'category'=>$categories->term_id, 'posts_per_page'=>'-1'));
$total_post = count($total_post);
?>
<li>
<div class="checkbox">
<input type="checkbox" id="cat<?php echo $categories->term_id; ?>" data-tax="category" data-name="<?php echo $categories->name; ?>" class="category_check" value="<?php echo $categories->term_id; ?>">
<label class="css-label" for="cat<?php echo $categories->term_id; ?>">
<span class="filter-name"><?php echo $categories->name; ?></span>
<span class="filter-count"><?php echo $total_post; ?></span>
<i class="icon fa fa-check"></i>
</label>
</div>
</li>
<?php } ?>
</ul>
</div>
<?php } ?>
I've created my own custom plugin for searching and filtering the search result.
1. Plugin file (index.php)
<?php
/*
Plugin Name: Search and Filter
Plugin URI: http://wordpress.org
Description: Search and Filter
Author: Naveen
Version: 1.0
*/
class SearchAndFilter{
public function __construct()
{
add_action('wp_enqueue_scripts', array($this, 'AddScript'));
add_action('wp_ajax_affordance_search_data' , array($this, 'AffordanceSearchData'));
add_action('wp_ajax_noprev_affordance_search_data' , array($this, 'AffordanceSearchData'));
add_action('wp_ajax_affordance_search_page_data' , array($this, 'AffordanceSearchPageData'));
add_action('wp_ajax_noprev_affordance_search_page_data' , array($this, 'AffordanceSearchPageData'));
add_shortcode('Search', array($this, 'CreateShortcode'));
}
public function AddScript()
{
wp_enqueue_script('saf-app', plugin_dir_url(__FILE__) . '/js/app.js', array('jquery'));
wp_localize_script('saf-app', 'my_ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
}
function CreateShortcode($atts)
{
ob_start();
$keyword = $_REQUEST['s'];
?>
<form action="<?php echo home_url('/'); ?>" method="get">
<input type="text" name="s" id="search_keyword" value="<?php echo $keyword; ?>" class="form-control search-input" placeholder="Search..." />
</form>
<div class="search-suggestion"></div>
<?php
$output = ob_get_clean();
return $output;
}
// search autocomplete
function AffordanceSearchData()
{
$args = array('post_type'=>array('post'),'status'=>'publish');
$output = '';
$output = '<ul class="grid effect-3" id="grid">';
if(isset($_POST['keyword']) && !empty($_POST['keyword']))
{
$args['s'] = $_POST['keyword'];
}
$wpPosts = new WP_Query($args);
if($wpPosts->have_posts()) :
while($wpPosts->have_posts()) :
$wpPosts->the_post();
$output .= '<li class="col-md-4 col-sm-6 col-xs-12">'.get_the_title().'</li>';
endwhile;
endif;
$output .= '<li>See All Result of '.$_POST['keyword'].' </li>';
$output .= '</ul>';
wp_reset_query();
echo $output; die;
}
// filters search data
function AffordanceSearchPageData()
{
$args = array('post_type'=>'post','status'=>'publish');
$output = '';
$output .= '<ul class="grid effect-3" id="grid">';
if(isset($_POST['keyword']) && !empty($_POST['keyword']))
{
$args['s'] = $_POST['keyword'];
}
if(isset($_POST['page_number']) && !empty($_POST['page_number']) && $_POST['page_number'] != 1){
$args['paged'] = $_POST['page_number'];
}
if(isset($_POST['categories']) && !empty($_POST['categories'])){
$args['cat'] = $_POST['categories'];
}
$wpPosts = new WP_Query($args);
if($wpPosts->have_posts()) :
while($wpPosts->have_posts()) :
$wpPosts->the_post();
$output .= '<li class="col-md-4 col-sm-6 col-xs-12">
<h3 class="resources-content-heading">'.get_the_title().'</h3>
<p class="resources-content-description">'.get_the_excerpt().'</p>
<div class="resources-action-area">
Read More <i class="fa fa-angle-right" aria-hidden="true"></i>
</div>
</li>';
endwhile;
else :
$output .= "No records";
endif;
wp_reset_query();
$output .= the_posts_pagination();
$output .= '</main>';
echo $output; die;
}
}
new SearchAndFilter();
2. Js File (app.js)
jQuery(document).ready(function ($) {
// on searching keyword
$('#search_keyword').keyup(function () {
var inputvalue = $(this).val();
if (inputvalue != '') {
GetSuggestion(inputvalue);
}
});
// on pagination click
$('.ajaxclick').on('click', "a", function () {
var page_number = $(this).attr('data-page-num');
//console.log(page_number);
var current_page = $('.ajaxclick .current').attr('data-page-num');
var keyword = $('#search_keyword').val();
GetSearchData(keyword, page_number);
});
// on category select
$('.category_check').on('click', function () {
var page_number = 1;
var keyword = $('#search_keyword').val();
var blogWrapper = $('.blogWrapper');
var catTagHTML = '<ul>';
blogWrapper.find('input.category_check:checked').each(function () {
catTagHTML += '<li><a class="exclude_cat" href="javascript:void(0)" data-cat-id="' + $(this).attr('value') + '">' + $(this).attr('data-name') + '</a></li>';
});
$('#selected-category-tags').html(catTagHTML);
GetSearchData(keyword, page_number);
});
// on tag click
$('#selected-category-tags').on('click', "a.exclude_cat", function () {
var page_number = 1;
var keyword = $('#search_keyword').val();
var catID = $(this).attr('data-cat-id');
$('#cat' + catID).attr('checked', false);
$(this).closest('li').remove();
GetSearchData(keyword, page_number);
});
function GetSuggestion(keyword) {
var formData = {
'action': 'affordance_search_data',
'keyword': keyword
}
$.ajax({
type: "post",
url: my_ajax_object.ajaxurl,
data: formData,
success: function (data) {
setTimeout(function () {
$('.search-suggestion').html(data);
}, 1000);
}
});
}
function GetSearchData(keyword, page_number) {
if (page_number == '') {
page_number = 1;
}
var blogWrapper = $('.blogWrapper');
var categories = [];
blogWrapper.find('input.category_check:checked').each(function () {
categories.push($(this).attr('value'));
});
var formData = {
'action': 'affordance_search_page_data',
'page_number': page_number,
'keyword': keyword,
'categories': categories,
}
$.ajax({
type: "post",
url: my_ajax_object.ajaxurl,
data: formData,
success: function (data) {
setTimeout(function () {
$('.site-main').html(data);
}, 1000);
}
});
}
});
Here I'm using ajax to achieve this functionality.

Load more data from database with Codeigniter and Ajax

I need help with a button for loading more data from the database. I've found examples, but too bad ones. Here is what I have so far:
The Ajax:
$('#revendas_conteudo .btn_carregar_mais').on('click', function(e) {
$.ajax({
url: '/auto/carros/load_more',
data: {
offset: $('#offset').val(),
limit: $('#limit').val()
},
success: function(data) {
$('#revendas_conteudo .lista_estoque').append(data);
}
});
});
My Controller method calling the Model load_more:
public function load_more()
{
$offset = $this->input->get('offset');
$limit = $this->input->get('limit');
$data['res'] = $this->Pesquisas_model->load_more($offset, $limit);
$data['offset'] = $offset + 1;
$data['limit'] = $limit + 1;
echo json_encode($data);
}
Pesquisas_model::load_more():
public function load_more($offset, $limit)
{
$this->db
->select(
'usuario.nome_razao_social AS nome_anunciante,' .
'modelo.modelo AS modelo,' .
'marca.marca AS marca,' .
'ano_modelo.ano AS ano,' .
'ano_modelo.valor AS valor,' .
'ano_modelo.combustivel AS combustivel,' .
'cambio.descricao_cambio AS descricao_cambio,' .
'estado.uf AS uf,' .
'cidade.nome_cidade AS nome_cidade,' .
'carro.*'
)
->join('usuario', 'usuario.id = carro.id_usuario')
->join('ano_modelo', 'ano_modelo.id = carro.id_ano_modelo')
->join('modelo', 'modelo.id = ano_modelo.id_modelo')
->join('marca', 'marca.id_marca = modelo.id_marca')
->join('cambio', 'cambio.id = carro.id_cambio')
->join('estado', 'estado.id = carro.id_estado')
->join('cidade', 'cidade.id = carro.id_cidade')
->order_by('marca.marca', 'ASC')
->limit($offset, $limit);
$query = $this->db->get($this->table);
if ($query) {
$data = array();
foreach ($query->result_array() as $row) {
$data[] = $row;
}
$query->free_result();
return $data;
}
}
The HTML:
<div class="lista_estoque">
<?php foreach ($pesquisas as $p) { ?>
<div class="item_estoque">
<div class="avatar">
<img src="/uploads/carros/destaque/<?php echo $p['imagem_destaque']; ?>"/>
</div>
<div class="texto_anuncio">
<h4><?php echo $p['modelo']; ?></h4>
<div class="detalhes">
<span><?php echo $p['marca'] . ' | ' . $p['combustivel'] . ' | ' . $p['cor']; ?></span>
<span><?php echo $p['ano']; ?></span>
<span><?php echo number_format($p['kilometragem'], 2) . 'km'; ?></span>
</div>
<span class="anunciante"><?php echo $p['nome_anunciante']; ?></span>
</div>
<div class="texto_anuncio_right">
<span class="preco"><?php echo 'R$ ' . $p['preco']; ?></span>
Veja Mais
</div>
</div>
<?php } ?>
<div class="carregar_mais">
<input type="hidden" name="limit" id="limit" value="1"/>
<input type="hidden" name="offset" id="offset" value="1"/>
<button class="btn btn_carregar_mais" data-val="0">Mostrar mais resultados</button>
</div>
So far what happens is a JSON code is appended to the end of the div. How do I make this data be converted into HTML and its classes?
converting a json text to a java
var text = '{ "employees" : [' +
'{ "firstName":"John" , "lastName":"Doe" },' +
'{ "firstName":"Anna" , "lastName":"Smith" },' +
'{ "firstName":"Peter" , "lastName":"Jones" } ]}';
var obj = JSON.parse(text);
use the js object
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML =
obj.employees[1].firstName + " " + obj.employees[1].lastName;
</script>
create a view called load_more.php in your view folder ..
Your Controller will be like this
public function load_more()
{
$offset = $this->input->get('offset');
$limit = $this->input->get('limit');
$data['pesquisas '] = $this->Pesquisas_model->load_more($offset, $limit);
$data['offset'] = $offset + 1;
$data['limit'] = $limit + 1;
data['load_more']=$this->load->view('load_more',$data);
}
And in your view load_more.php
<?php foreach ($pesquisas as $p) { ?>
<div class="item_estoque">
<div class="avatar">
<img src="/uploads/carros/destaque/<?php echo $p['imagem_destaque']; ?>"/>
</div>
<div class="texto_anuncio">
<h4><?php echo $p['modelo']; ?></h4>
<div class="detalhes">
<span><?php echo $p['marca'] . ' | ' . $p['combustivel'] . ' | ' . $p['cor']; ?></span>
<span><?php echo $p['ano']; ?></span>
<span><?php echo number_format($p['kilometragem'], 2) . 'km'; ?></span>
</div>
<span class="anunciante"><?php echo $p['nome_anunciante']; ?></span>
</div>
<div class="texto_anuncio_right">
<span class="preco"><?php echo 'R$ ' . $p['preco']; ?></span>
Veja Mais
</div>
</div>
<?php } ?>
Jquery
success: function(data) {
var res= JSON.parse(data);
$('#revendas_conteudo .lista_estoque').append(data.load_more);
$('.carregar_mais input[name=limit]').val(data.limit);
$('.carregar_mais input[name=offset]').val(data.offset);
});
In the following function in controller, you need to add a view where you echo the content properly with html markups and classes as defined by you.
Currently, you are echoing the json_encode format. That's why it is printing as it is.
public function load_more()
{
$offset = $this->input->get('offset');
$limit = $this->input->get('limit');
$data['res'] = $this->Pesquisas_model->load_more($offset, $limit);
$data['offset'] = $offset + 1;
$data['limit'] = $limit + 1;
//echo json_encode($data);
$this->load->view('load-more',$data['res']);
}
Most of the answers here have led me to the solution. Sadly I can't tag all of them as the correct answer, so allow me to post what I did:
First, this is the full Ajax. I could not make it work with an external file as suggested, so it is like this:
$('#revendas_conteudo .btn_carregar_mais').on('click', function(e) {
$.ajax({
url: '/auto/carros/load_more',
data: {
'offset': $('#offset').val(),
'limit': $('#limit').val()
},
success: function(data) {
var obj = JSON.parse(data);
var i = 0;
var max = obj.total === obj.offset;
$('#limit').val(obj.limit);
$('#offset').val(obj.offset);
$.each(obj, function(k, v) {
$('#revendas_conteudo .load_more').append(
'<div class="item_estoque">' +
'<div class="avatar">' +
'<img src="/uploads/carros/destaque/' + obj.res[i].imagem_destaque + '"/>' +
'</div>' +
'<div class="texto_anuncio">' +
'<h4>' + obj.res[i].modelo + '</h4>' +
'<div class="detalhes">' +
'<span>' + obj.res[i].marca + ' | ' + obj.res[i].combustivel + ' | ' + obj.res[i].cor + '</span>' +
'<span>' + obj.res[i].ano + '</span>' +
'<span>' + obj.res[i].kilometragem + ' km</span>' +
'</div>' +
'<span class="anunciante">' + obj.res[i].nome_anunciante + '</span>' +
'</div>' +
'<div class="texto_anuncio_right">' +
'<span class="preco"> R$ ' + obj.res[i].preco + '</span>' +
'Veja Mais' +
'</div>' +
'</div>'
).show('slow');
i++;
if (max) {
$('#revendas_conteudo .btn_carregar_mais').css({backgroundColor: '#999'}).html('Sem mais resultados').attr('disabled', true);
}
});
}
});
});
In here I append every new result to the div.load_more, and if the total is identical to the current offset, it means it has already shown all the values, making the button unavailable for clicking.
Here, the controller method:
public function load_more()
{
$offset = $this->input->get('offset');
$limit = $this->input->get('limit');
$data['res'] = $this->Pesquisas_model->load_more($offset, $limit);
$data['total'] = $this->Pesquisas_model->count_all();
if ($data['res']) {
$data['offset'] = $offset + 2;
$data['limit'] = $limit;
echo json_encode($data);
}
}

Cart update with ajax and php

I'm learning how can i use ajax, jquery and php to update a cart. I found this code and i'm trying to adapt it, but without success. The problem is that i can't add any item to the cart and after a search on google still don't understand where is the problem.
<script>
$(document).ready(function(){
$(".form-item").submit(function(e){
var form_data = $(this).serialize();
var button_content = $(this).find('button[type=submit]');
button_content.html('Adding...'); //Loading button text
$.ajax({ //make ajax request to cart_process.php
url: "../../cart_process.php",
type: "POST",
dataType:"json", //expect json value from server
data: form_data
}).done(function(data){ //on Ajax success
$("#cart-info").html(data.items); //total items in cart-info element
button_content.html('Add to Cart'); //reset button text to original text
alert("Item added to Cart!"); //alert user
if($(".shopping-cart-box").css("display") == "block"){ //if cart box is still visible
$(".cart-box").trigger( "click" ); //trigger click to update the cart box.
}
})
e.preventDefault();
});
//Show Items in Cart
$( ".cart-box").click(function(e) { //when user clicks on cart box
e.preventDefault();
$(".shopping-cart-box").fadeIn(); //display cart box
$("#shopping-cart-results").html('<img src="images/ajax-loader.gif">'); //show loading image
$("#shopping-cart-results" ).load( "../../cart_process.php", {"load_cart":"1"}); //Make ajax request using jQuery Load() & update results
});
//Close Cart
$( ".close-shopping-cart-box").click(function(e){ //user click on cart box close link
e.preventDefault();
$(".shopping-cart-box").fadeOut(); //close cart-box
});
//Remove items from cart
$("#shopping-cart-results").on('click', 'a.remove-item', function(e) {
e.preventDefault();
var pcode = $(this).attr("data-code"); //get product code
$(this).parent().fadeOut(); //remove item element from box
$.getJSON( "../../cart_process.php", {"remove_code":pcode} , function(data){ //get Item count from Server
$("#cart-info").html(data.items); //update Item count in cart- info
$(".cart-box").trigger( "click" ); //trigger click on cart-box to update the items list
});
});
});
prodotto.php Here i have the description of the product, the form to select quantity and the button to add the product to the cart
<?php
require_once("../inc/config.php");
require_once(ROOT_PATH . "inc/database.php");
require_once(ROOT_PATH . "prodotti/prod.php");
require_once(ROOT_PATH . "login/user.php");
sec_session_start();
if(isset($_GET['sku'])) {
$sku = intval($_GET['sku']);
$prodotto = get_product_single($sku);
}
if(empty($prodotto)){
header("Location:" . BASE_URL);
exit();
}
include(ROOT_PATH . "inc/header.php");
include(ROOT_PATH . "inc/side-menu.php");
try{
$results = $db->prepare("SELECT * from prodotti WHERE sku = ?");
$results->bindParam(1,$sku);
$results->execute();
$prodotto = $results->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
echo "Nessun prodotto da visualizzare con queste caratteristiche";
die();
}
?>
<div id="content" class="large-8 columns round-all" role="main" itemscope itemtype="http://schema.org/LocalBusiness" style="background-color:#eee;padding-right:1em;">
<div class="row" style="padding-right:1em;">
<?php
$categoria = get_category($prodotto['categoria']);
?>
<nav class="breadcrumbs" role="menubar" aria-label="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<li role="menuitem"><span itemprop=”title”><?php echo $categoria['nome'];?></span></li>
<li role="menuitem" class="current"><span itemprop=”title”><?php echo $prodotto['nome'];?></span></li>
</nav>
<a href="#" class="cart-box" id="cart-info" title="View Cart">
<?php
if(isset($_SESSION["products"])){
echo count($_SESSION["products"]);
}else{
echo 0;
}
?>
<div class="shopping-cart-box">
<a href="#" class="close-shopping-cart-box" >Close</a>
<h3>Your Shopping Cart</h3>
<div id="shopping-cart-results">
</div>
</div>
<?php
echo '<li role="menuitem" style="list-style-type:none;">
<div class="large-12 columns" style="background-color:#fff;" itemscope itemtype="http://schema.org/Product">
<div class="small-1 medium-2 large-4 columns" style="border:10px #eee solid">
<span itemprop ="image"><img src="' . BASE_URL . 'img/profumo-hugo-boss.jpg";/></span>
</div>
<div class="small-1 medium-4 large-8 columns" >
<span itemprop="name"><h3>'.$prodotto['nome'].'</h3></span>
<h6>Codice: ' . $prodotto['sku'] . '</h6>
<span itemprop="price"><h6>Prezzo: <span style="color:red;font-weight:bold;";>' . $prodotto['prezzo'] . '<span itemprop="priceCurrency">€</span></span></h6></span>
<span itemprop="description"><p>'.$prodotto['descrizione'].'</p></span>';?>
<form class="form-item">
<div class="small-1 medium-2 large-4">
<label for="quantita">Quantità</label>
<select name="quantita" id="quantita">
<option value="1">1 </option>
<option value="2">2 </option>
<option value="3">3 </option>
<option value="4">4 </option>
<option value="5">5 </option>
<option value="6">6 </option>
<option value="7">7 </option>
<option value="8">8 </option>
<option value="9">9 </option>
<option value="10">10 </option>
</select>
</div>
<div class="small-1 medium-2 large-4">
<input type="hidden" name="sku" value="<?php echo $prodotto['sku'];?>"/>
<input type="hidden" name="id_sessione" value="<?php echo $_SESSION['id'];?>"/>
<input type="submit" value="Aggiungi al carrello" class="button" name="submit">
</div>
</form>
</div>
</div>
</li>
</div>
</div>
</div>
</div>
Cart_process.php
include_once("../inc/config.php");
sec_session_start();
############# add products to session #########################
if(isset($_POST["sku"]))
{
foreach($_POST as $key => $value){
$new_product[$key] = filter_var($value, FILTER_SANITIZE_STRING); //create a new product array
}
//we need to get product name and price from database.
$statement = $db->prepare("SELECT nome, sku FROM prodotti WHERE sku=? LIMIT 1");
$statement->bindParam(1, $new_product['sku']);
$statement->execute();
$prodotto = $statement-fetch(PDO::FETCH_ASSOC);
while($prodotto){
$new_product["nome"] = $prodotto['nome']; //fetch product name from database
$new_product["sku"] = $prodotto['sku']; //fetch product sku from database
if(isset($_SESSION["products"])){ //if session var already exist
if(isset($_SESSION["products"][$new_product['sku']])) //check item exist in products array
{
unset($_SESSION["products"][$new_product['sku']]); //unset old item
}
}
$_SESSION["products"][$new_product['sku']] = $new_product; //update products with new item array
}
$total_items = count($_SESSION["products"]); //count total items
die(json_encode(array('items'=>$total_items))); //output json
}
################## list products in cart ###################
if(isset($_POST["load_cart"]) && $_POST["load_cart"]==1)
{
if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){ //if we have session variable
$cart_box = '<ul class="cart-products-loaded">';
$total = 0;
foreach($_SESSION["products"] as $product){ //loop though items and prepare html content
//set variables to use them in HTML content below
$product_name = $product["nome"];
/*$product_price = $product["product_price"];
*/$product_code = $product["sku"];/*
$product_qty = $product["product_qty"];
$product_color = $product["product_color"];
$product_size = $product["product_size"];
*/
$cart_box .= "<li> $product_name ×</li>";
//$subtotal = ($product_price * $product_qty);
//$total = ($total + $subtotal);
}
$cart_box .= "</ul>";
//$cart_box .= '<div class="cart-products-total">Total : '.$currency.sprintf("%01.2f",$total).' <u>Check-out</u></div>';
die($cart_box); //exit and output content
}else{
die("Your Cart is empty"); //we have empty cart
}
}
################# remove item from shopping cart ################
if(isset($_GET["remove_code"]) && isset($_SESSION["products"]))
{
$product_code = filter_var($_GET["remove_code"], FILTER_SANITIZE_STRING); //get the product code to remove
if(isset($_SESSION["products"][$product_code]))
{
unset($_SESSION["products"][$product_code]);
}
$total_items = count($_SESSION["products"]);
die(json_encode(array('items'=>$total_items)));
}
Moving forward from our discussion in the comments, I will be posting a functional behavior of the code with a sample data from database since you wanted it to be dynamic.
As this was for learning purpose I've had used prepared statements with some msql_. (both in different files) Please note that msql_
is deprecated and I urge not to use it.
Before starting, I assume you have all the required files downloaded and saved in the correct path and used either method (filesystem/storing directly to database) for the images, I have however used the filesystem behavior. Now, there are three tables used from the database:
1) category table with columns as follow:
cat_id
cat_name
2) item table which has the columns as follow:
item_id
item_name
item_quantity
item_size
cat_id (FK from category table)
item_color
3) products_list table with following columns:
id (AI, PK)
product_name
product_desc
product_code
product_image
item_id (FK from item table)
product_price
product_discount
Now, Starting with the very first page.
index.php
<?php
session_start(); //start session
include("config.php"); //include config file
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script>
$(document).ready(function(){
$(".form-item").submit(function(e){
var form_data = $(this).serialize();
var button_content = $(this).find('button[type=submit]');
button_content.html('Adding...');
$.ajax({
url: "cart_process.php",
type: "POST",
dataType:"json",
data: form_data
}).done(function(data){
$("#cart-info").html(data.items);
button_content.html('Add to Cart');
alert("Item added to Cart!");
if($(".shopping-cart-box").css("display") == "block"){
$(".cart-box").trigger( "click" );
}
})
e.preventDefault();
});
//Show Items in Cart
$( ".cart-box").click(function(e) {
e.preventDefault();
$(".shopping-cart-box").fadeIn();
$("#shopping-cart-results").html('<img src="images/ajax-loader.gif">');
$("#shopping-cart-results" ).load( "cart_process.php", {"load_cart":"1"});
});
//Close Cart
$( ".close-shopping-cart-box").click(function(e){
e.preventDefault();
$(".shopping-cart-box").fadeOut();
});
//Remove items from cart
$("#shopping-cart-results").on('click', 'a.remove-item', function(e) {
e.preventDefault();
var pcode = $(this).attr("data-code");
$(this).parent().fadeOut();
$.getJSON( "cart_process.php", {"remove_code":pcode} , function(data){
$("#cart-info").html(data.items);
$(".cart-box").trigger( "click" );
});
});
});
</script>
<?php
$que = "SELECT * FROM category";
$run = mysql_query($que);
$j = 0;
while($row = mysql_fetch_array($run))
{
$cat_idd[$j] = $row['cat_id'];
$cat_namee[$j] = $row['cat_name'];
$j++;
}
for($i = 0; $i < count($cat_idd); $i++)
{
$que2 = "SELECT * FROM item WHERE cat_id = '$cat_idd[$i]' ";
$result = mysql_query($que2);
$run = mysql_num_rows($result);
echo"<table>";
echo"<th id = 'hidden'></th>";
echo"<tr>";
echo"<td id = 'side' width = '110'>";
echo " "."<a href='index.php?id=$cat_idd[$i]' style = 'text-decoration: none;' >".$cat_namee[$i]." (".$run.")</a><br><br>";
echo "</td>";
echo "</tr>";
echo "</table>";
}
require('config.php');
if(isset($_GET['id']))
{
$cat_id = $_GET['id'];
$que = "SELECT * FROM item WHERE cat_id = '$cat_id'";
$run = mysql_query($que);
?>
<form class="form-item">
<a href="#" class="cart-box" id="cart-info" title="View Cart">
<?php
if(isset($_SESSION["products"])){
echo count($_SESSION["products"]);
}else{
echo 0;
}
?>
</a>
<div class="shopping-cart-box">
<a href="#" class="close-shopping-cart-box" >Close</a>
<h3>Your Shopping Cart</h3>
<div id="shopping-cart-results">
</div>
</div>
<?php
while($row = mysql_fetch_array($run))
{
$i_id = $row['item_id'];
$i_name = $row['item_name'];
$i_quantity = $row['item_quantity'];
$i_size = $row['item_size'];
$i_color = $row['item_color'];
?>
<?php
$query3 = "SELECT product_name, product_price, product_desc, product_code, product_image, product_discount FROM products_list WHERE item_id = '$i_id' ";
$run3 = mysql_query($query3);
while($row3 = mysql_fetch_array($run3)) {
?>
<ul class="products-wrp">
<li>
<form class="form-item">
<h4><?php echo $row3['product_name']; ?></h4>
<div><img src="images/<?php echo $row3['product_image']; ?>"height = "150" width = "180"></div>
<?php echo "Availabe Quantity: " . $i_quantity . "<br>"; ?>
<?php
if($row3['product_discount'] == 0)
{
echo "Rs. " . $row3['product_price'];
}
else
{
echo "NOW ". $row3['product_discount'] . "% OFF!";
echo '<div>Rs. <span style = "text-decoration: line-through;">'.$row3['product_price'].'</span></div>';
$discount = ((($row3['product_discount'])/100) * $row3['product_price']);
$f_price = ($row3['product_price'] - $discount);
echo "Rs. ". $f_price . ".00" ;
}
?>
<div class="item-box">
<div>
Color :
<?php
$arr = $row["item_color"];
$exp = explode("," , $arr);
echo "<select name='product_color'>";
foreach($exp as $key=>$val) {
echo "<option value='" . $val . "'>" . $val . "</option>";
}
echo "</select>";
?>
<!-- <select name="product_color">
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Orange">Orange</option>
</select>
-->
</div>
<div>
Qty :
<input type = "number" name = "product_qty" min = "1" max = "<?php echo $i_quantity; ?>"
value = "1" title = "Please Enter the Numbers Below Available Quantity Only.">
<!--
<select name="product_qty">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
-->
<div>
Size :
<?php
$arr = $row["item_size"];
$exp = explode("," , $arr);
echo "<select name='product_size'>";
foreach($exp as $key=>$val) {
echo "<option value='" . $val . "'>" . $val . "</option>";
}
echo "</select>";
?>
<input name="product_code" type="hidden" value="<?php echo $row3['product_code']; ?>">
<button type="submit">Add to Cart</button>
</div>
</form>
</li>
</ul>
</div>
<?php } } }?>
</body>
</html>
Now the very first thing as you click on "Add to Cart" happens is the ajax request to cart_process.php with a json value expected to be returned.
cart_process.php
<?php
session_start();
$db_username = 'root';
$db_password = '';
$db_name = 'yourdbnamehere';
$db_host = 'localhost';
$currency = 'Rs. ';
$shipping_cost = 500;
$taxes = array(
'VAT' => 12,
'Service Tax' => 5,
'Other Tax' => 10
);
$mysqli_conn = new mysqli($db_host, $db_username, $db_password,$db_name);
if ($mysqli_conn->connect_error) {
die('Error : ('. $mysqli_conn->connect_errno .') '. $mysqli_conn->connect_error);
// add products to session
if(isset($_POST["product_code"]))
{
foreach($_POST as $key => $value){
$new_product[$key] = filter_var($value, FILTER_SANITIZE_STRING);
}
$statement = $mysqli_conn->prepare("SELECT product_name, product_price, product_discount FROM products_list WHERE product_code=? LIMIT 1");
$statement->bind_param('s', $new_product['product_code']);
$statement->execute();
$statement->bind_result($product_name, $product_price, $product_discount);
while($statement->fetch()){
$new_product["product_name"] = $product_name;
$new_product["product_price"] = $product_price;
$new_product["product_discount"] = $product_discount;
if($product_discount == 0)
{
$product_price = $product_price;
}
else
{
$discount = (($product_discount/100) * $product_price);
$product_price = $product_price - $discount;
}
if(isset($_SESSION["products"])){
if(isset($_SESSION["products"][$new_product['product_code']]))
{
unset($_SESSION["products"][$new_product['product_code']]);
}
$_SESSION["products"][$new_product['product_code']] = $new_product;
}
$total_items = count($_SESSION["products"]);
die(json_encode(array('items'=>$total_items)));
}
// list products in cart
if(isset($_POST["load_cart"]) && $_POST["load_cart"]==1)
{
if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){
$cart_box = '<ul class="cart-products-loaded">';
$total = 0;
foreach($_SESSION["products"] as $product){
$product_name = $product["product_name"];
$product_price = $product["product_price"];
$product_code = $product["product_code"];
$product_qty = $product["product_qty"];
$product_color = $product["product_color"];
$product_size = $product["product_size"];
$product_discount = $product["product_discount"];
if($product_discount == 0)
{
$product_price = $product_price;
}
else
{
$discount = (($product_discount/100) * $product_price);
$product_price = $product_price - $discount;
}
$cart_box .= "<li> $product_name (Qty : $product_qty | $product_color | $product_size ) — $currency ".sprintf("%01.2f", ($product_price * $product_qty)). " ×</li>";
$subtotal = ($product_price * $product_qty);
$total = ($total + $subtotal);
}
$cart_box .= "</ul>";
$cart_box .= '<div class="cart-products-total">Total : '.$currency.sprintf("%01.2f",$total).' <u>Check-out</u></div>';
die($cart_box);
}else{
die("Your Cart is empty");
}
}
// remove item from shopping cart
if(isset($_GET["remove_code"]) && isset($_SESSION["products"]))
{
$product_code = filter_var($_GET["remove_code"], FILTER_SANITIZE_STRING);
if(isset($_SESSION["products"][$product_code]))
{
unset($_SESSION["products"][$product_code]);
}
$total_items = count($_SESSION["products"]);
die(json_encode(array('items'=>$total_items)));
}
Now comes the part when you click on "Check-out" in your add-to-cart box. It takes you to another page (the last one in our case) where you can see all the products that you have bought.
view_cart.php
<?php
session_start();
include("config.inc.php"); //one written above in cart_process.php
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Review Your Cart Before Buying</title>
<link href="style/style.css" rel="stylesheet" type="text/css">
<body>
<?php
if(isset($_COOKIE['user']))
{
$last = $_COOKIE['user'];
echo 'SignOut';
echo "Logged in: ". $last . "<br><br>";
echo '<h3 style="text-align:center">Review Your Cart Before Buying</h3>';
if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){
$total = 0;
$list_tax = '';
$cart_box = '<ul class="view-cart">';
foreach($_SESSION["products"] as $product){
$product_name = $product["product_name"];
$product_qty = $product["product_qty"];
$product_price = $product["product_price"];
$product_code = $product["product_code"];
$product_color = $product["product_color"];
$product_size = $product["product_size"];
$product_discount = $product["product_discount"];
if($product_discount == 0)
{
$product_price = $product_price;
}
else
{
$discount = (($product_discount/100) * $product_price);
$product_price = $product_price - $discount;
}
$item_price = sprintf("%01.2f",($product_price * $product_qty)); // price x qty = total item price
$cart_box .= "<li> $product_code – $product_name (Qty : $product_qty | $product_color | $product_size) <span> $currency$item_price </span></li>";
$subtotal = ($product_price * $product_qty);
$total = ($total + $subtotal);
}
$grand_total = $total + $shipping_cost;
foreach($taxes as $key => $value){
$tax_amount = round($total * ($value / 100));
$tax_item[$key] = $tax_amount;
$grand_total = $grand_total + $tax_amount;
}
foreach($tax_item as $key => $value){
$list_tax .= $key. ' '. $currency. sprintf("%01.2f", $value).'<br />';
}
$shipping_cost = ($shipping_cost)?'Shipping Cost : '.$currency. sprintf("%01.2f", $shipping_cost).'<br />':'';
$cart_box .= "<li class=\"view-cart-total\">$shipping_cost $list_tax <hr>Payable Amount : $currency ".sprintf("%01.2f", $grand_total)."</li>";
$cart_box .= "</ul>";
echo $cart_box;
echo 'Confirm Purchase';
}else{
echo "Your Cart is empty";
}
}
else
if(!isset($_COOKIE['user']))
{
echo "You must be logged in to purchase!<br>";
echo 'Login';
}
?>
</body>
</html>
I have run and checked all the processing before posting this here, So it should help you understand the exact behavior and the way to move along.
Cheers.

PHP Class to Generate HTML?

Anyone know of any classes written for php that can clean up your code a bit?
Something like,
$htGen = new HTMLGenerator();
$htGen->newDOM('div', 'here is what goes in the div', 'optionalID', 'optionalClass');
Or does that just sound redundant?
I end up with some complex looking mish-mashes of html and php sometimes that I feel could be simplified a bit eg my latest cms bit;
foreach($details as $detail){
$d = unserialize($detail);
if($ad){
print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
}else{
if($d->get_info('orphan')){
echo '<li class="classRow orphan">' . "\n";
echo '<div class="orphan" style="display:none">orphan</div>' . "\n";
}else{
echo '<li class="classRow">' . "\n";
echo '<div class="orphan" style="display:none"></div>' . "\n";
}
echo '<div class="classNumbers" id="' . $d->get_info('class ID') . '" style="display:none"></div>' . "\n";
echo '<div class="rowBG" style="overflow:hidden;width:100%">';
echo '<div class="startTime"></div>' . "\n";
echo '<div class="details"><span class="classes">' . $d->get_info('class number') . '</span> - <input class="detailInput" type="text" value="' . $d->get_info('class description') . '"/><div class="editButton"><a class="editExpand">options(+)</a></div></div>' . "\n";
echo '<div class="interval">';
echo '<input class="intervalInput" type="text" value="' . $d->get_info('interval') . '" maxlength="5"/>';
echo '</div>' . "\n";
echo '<div class="numRiders"><input class="numRidersInput" type="text" value="' . $d->get_info('num riders') . '"/></div>' . "\n";
echo '</div>';
echo '<div class="classOptions">' . "\n";
echo '<div class="selectRingMove">Move to Ring:<select id="ringSwap"><option>Select A Ring</option>' . get_ring_options() . '</select></div>' . "\n";
if($d->get_info('online sign up') != 'false'){
echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp" checked/></div>' . "\n";
}else{
echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp"/></div>' . "\n";
}
if($d->get_info('water and drag')){
echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox" checked/><input type="text" value="' . $d->get_info('water and drag') . '" maxlength="2" class="wdInput"> min</div>' . "\n";
}else{
echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox"/><input type="text" value="20" maxlength="2" class="wdInput"> min</div>' . "\n";
}
if($d->get_info('ghost riders')){
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') . '"></div>' . "\n";
}else{
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
}
echo '</div>' . "\n";
echo '</li>' . "\n";
if($d->get_info('water and drag')){
echo '<li class="waterAndDragRow" style="display:block;"><span class="wdStartTime">08:33am</span> - <span class="wdEndTime">08:34am</span> <input type="text" class="wdDescription" value="' . $d->get_info('water and drag description') . '"></li>';
}
}
}
Or, if you know of a cleaner way to write long blocks of intermingled php vars and html... (not a big fan of EOF>>>)
Thanks in advance.
I guess it could be done with http://www.php.net/manual/en/class.domdocument.php. But that isn't really a good way to do it.
I agree that your code code sample isn't very clear, you could consider something like:
<ul>
<?php foreach ($items as $item): ?>
<li>
<?=$item['something']?>
<?php if ($item['foo'] == 'bar'): ?>
<ul>
<li>bar</li>
</ul>
<?php else: ?>
<ul>
<li>foo</li>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>
<ul>
That's a lot better imho, I use it like that in my views.
Btw, you should validate your html output. For example, a div-element isn't allowed in a li-element.
edit:
Obviously, the following code:
<?php if ($item['foo'] == 'bar'): ?>
<ul>
<li>bar</li>
</ul>
<?php else: ?>
<ul>
<li>foo</li>
</ul>
<?php endif; ?>
Could be replaced by:
<ul>
<li><?=($item['foo'] == 'bar' ? 'bar' : 'foo')?></li>
</ul>
I'm working on a simple DSL that addresses this common task. It's called htmlgen, mirrored on packagist.
Here's an example
use function htmlgen\html as h;
h('#wrapper',
h('h1.title', 'Hello, World'),
h('p',
h('comment', 'link to something'),
h('a', ['href'=>'https://duckduckgo.com'], 'search the internet')
)
);
Here's the output (actual output does not have whitespace)
<div id="wrapper">
<h1 class="title">Hello, World</h1>
<p>
<!-- link to something -->
search the internet
</p>
</div>
It's very new but at ~200 lines of source, it's already very powerful. Fork it and make adjustments or send me a note with suggestions.
The main idea of generating HTML is to keep HTML as is.
Just divide your script into 2 parts: prepare data part and display data part. A latter one should contain mostly HTML with some PHP control structures. Of course, there should be as less PHP code as possible. Move all unnecessary PHP code into first part.
Well to sum up all of the above:
there should be nothing to unserialize in the $details array. Have your data prepared already
<? foreach ($details as $d): ?>
<li class="classRow orphan">
<div class="orphan" style="display:none"><? if ($d->get_info('orphan')): ?>orphan<? endif ?></div>
<div class="classNumbers" id="<?= $d->get_info('class ID') ?>" style="display:none"></div>
<div class="rowBG" style="overflow:hidden;width:100%">
<div class="startTime"></div>
<div class="details">
<span class="classes"><?= $d->get_info('class number') ?></span> -
<input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
<div class="editButton">
<a class="editExpand">options(+)</a>
</div>
</div>
<div class="interval">
<input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
</div>
<div class="numRiders">
<input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
</div>
</div>
<div class="classOptions">
<div class="selectRingMove">Move to Ring:
<select id="ringSwap">
<option>Select A Ring</option>
<?= foreach (get_ring_options() as $value => $option): ?>
<option value="<?=$value?>"><?=$option?></option>
<? endforeach ?>
</select>
</div>
<div class="signUpContainer">Sign-Up
<input type="checkbox" class="signUp" <? if (!$d->get_info('online sign up'): ?>checked<? endif ?>/>
</div>
and so on.
The main rule should be DRY: Do not Repeat Yourself.
Do not repeat blocks of code if there is only one word difference.
But enclose that word into condition
Note that get_ring_options() was replaced with proper code.
Do not make functions that return HTML, but an array instead.
Instead of a class, consider a library of functions to generate HTML. I didn't use a class to make the code that you end up writing concise but expressive. With a class you must create an instance and use that variable, or make the methods static and write static references.
With this technique creating HTML for an image that is a link looks like this:
a('/example/url', img('image_url', $altText));
This is based on a script I once created. First the generic functions to generate HTML elements and attributes:
function tag($tag, $text, $attributes = array()) {
return "<$tag" . attributesToArray($attributes) . ">$text</$tag>";
}
function minimizedTag($tag, $attributes = array()) {
return "<$tag" . attributesToArray($attributes) . " />";
}
function attributesToArray($attributes = array()){
$a = '';
foreach ($attributes as $attribute => $value) {
$a .= " $attribute='$value'";
}
return $a;
}
Then add functions named according to the HTML elements they create, like a() and img() to create a link and image:
function a($link, $text, $attributes = array()) {
$a = array('href' => $link);
foreach ($attributes as $attribute => $value) {
$a[$attribute] = $value;
}
return tag('a', $text, $a);
}
function img($url, $alt = null) {
$a = array('src' => $url);
if (!is_null($alt)){
if (is_array($alt)){
$a = array_merge($a, $alt);
} else {
$a['alt'] = $alt;
}
}
return minimizedTag('img', $a);
}
Choose the parameters to pass common attributes wisely to make the library easier to use.
I'll probably get downvoted for recommending short tags, but here's what I do. I put all the <? and ?> tags at column 1 so that the code reads like a mix of PHP and HTML. No echo statements is the goal.
foreach ($details as $detail) {
$d = unserialize($detail);
if ($ad) {
print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
}
else {
if ($d->get_info('orphan')) {
?> <li class="classRow orphan">
<div class="orphan" style="display:none">orphan</div>
<? }
else {
?> <li class="classRow">
<div class="orphan" style="display:none"></div>
<? }
?> <div class="classNumbers" id="<?= $d->get_info('class ID') ?>"
style="display:none"></div>
<div class="rowBG" style="overflow:hidden;width:100%">
<div class="startTime"></div>
<div class="details">
<span class="classes"><?= $d->get_info('class number') ?></span> -
<input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
<div class="editButton">
<a class="editExpand">options(+)</a>
</div>
</div>
<div class="interval">
<input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
</div>
<div class="numRiders">
<input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
</div>
</div>
<div class="classOptions">
<div class="selectRingMove">
Move to Ring:
<select id="ringSwap">
<option>Select A Ring</option>
<?= get_ring_options() ?>
</select>
</div>
<? if ($d->get_info('online sign up') != 'false') {
?> <div class="signUpContainer">
Sign-Up
<input type="checkbox" class="signUp" checked/>
</div>
<? }
else {
?> <div class="signUpContainer">
Sign-Up
<input type="checkbox" class="signUp"/>
</div>
<? }
if ($d->get_info('water and drag')) {
?> <div class="wdBoxContainer">
<select id="wdDescrip">
<option>WATER AND DRAG</option>
<option>COURSE CHANGE & WALK</option>
<option>OTHER</option>
</select>
<input type="checkbox" class="wdBox" checked/>
<input type="text" value="<?= $d->get_info('water and drag') ?>" maxlength="2" class="wdInput"> min
</div>
<? }
else {
?> <div class="wdBoxContainer">
<select id="wdDescrip">
<option>WATER AND DRAG</option>
<option>COURSE CHANGE & WALK</option>
<option>OTHER</option>
</select>
<input type="checkbox" class="wdBox"/>
<input type="text" value="20" maxlength="2" class="wdInput"> min
</div>
<? }
if ($d->get_info('ghost riders')) {
?> <div class="ghostRidersContainer">
Ghost Riders
<input type="checkbox" checked class="ghostBox">
<input type="text" maxlength="2" class="ghostRiderInput" value="<?= $d->get_info('ghost riders') ?>">
</div>
<? }
else {
?> <div class="ghostRidersContainer">
Ghost Riders
<input type="checkbox" class="ghostBox">
<input type="text" maxlength="2" class="ghostRiderInput">
</div>
<? }
?> </div>
</li>
<? if ($d->get_info('water and drag')) {
?> <li class="waterAndDragRow" style="display:block;">
<span class="wdStartTime">08:33am</span> -
<span class="wdEndTime">08:34am</span>
<input type="text" class="wdDescription" value="<?= $d->get_info('water and drag description') ?>">
</li>
<? }
}
}
In regards to PHP classes to generate HTML, you could use http://api20.cakephp.org/class/html-helper an object from the cake PHP framework.
The others have already addressed your not so clean code.
It uses this format: div( $class = NULL, $text = NULL, $options = array ( ) )
why not create your own clases?? or at least some functions... and i saw that you use alot of IF, you may clean it using vairables like when you have
if($d->get_info('ghost riders')){
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') . '"></div>' . "\n";
}else{
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
}
you could write:
$check = ($d->get_info('ghost riders'))?"checked":"";
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" '.$check.' class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') . '"></div>' . "\n";
it will look cleaner :) I've created a Form class that helps me when i have to create forms and the code is more legible
Do not mix html and php code!
I would do this: https://github.com/HanKruma/Tag-Generator
"Tag gen"
<?php
namespace Main;
/**
* Description of Tag
*
* #author HanKrum
*/
class Tag {
private $_tags = ['doctype', 'br', 'hr', 'input', 'meta', 'base', 'basefont', 'img', 'source'];
public function __call($name, $arguments) {
$attr = null;
$text = null;
if (\in_array($name, $this->_tags)) {
$name = $name == $this->_tags[0] ? '!' . $name . ' html' : $name;
foreach ($arguments as $v) {
$attr .= ' ' . $v;
}
return '<' . $name . $attr . '>' . "\n";
}
$br = 0;
$count = \count($arguments);
foreach ($arguments as $v) {
$br ++;
if ($br == $count) {
$text = $v;
} else {
if (!$v) {
$space = null;
} else {
$space = ' ';
}
$attr .= $space . $v;
}
}
return '<' . $name . $attr . '>' . $text . '</' . $name . '>' . "\n";
}
}
And use this that:
<?php
$ob = new \Main\Tag();
echo $ob->input('class="doc"', 'placeholder="Title"', 'name="title"');
echo $ob->span(null, 'Text');
exit($ob->button('class="submit"', 'Write');
For those looking for the simple start. This is enough to generate a wide variety of elements.
This will create any kind of element, give some content, a class, and an id.
You will have to handle special cases yourself, if you are using it in your app.
<?php
/**
* HTML - Simplest html element builder
* - #param1 Element name
* - #param2 Class name
* - #param3 ID
* - #param2 Element content
*/
class HTML{
/**
* Create a new html element
*/
private static function core($element, $content) {
return "<" . $element . ">" . $content . "</" . $element . ">";
}
/**
* Add a new param to a html element
*/
private static function addParam($elem, $param, $value) {
if (is_null($value)){return $elem;}
return implode(" $param=\"" . $value . '">', explode(">", $elem, 2));
}
/**
* Return an element with a class and an id
*/
public static function create($element, $content=null, $class=null, $id=null) {
return self::addParam(self::addParam(self::core($element, $content), "class", $class) , "id", $id);
}
}
// Examples
echo HTML::create("div", "This is it!", "redclass", "niceid");
echo PHP_EOL;
$html = new HTML();
echo HTML::create("button", "Click me!", "button", "48151");
echo PHP_EOL;
echo $html->create("p", "A paragraph");
echo PHP_EOL;
echo $html->create("h3", "Hello world!");
// OUTPUT
//<div class="redclass" id="niceid">This is wtf</div>
//<button class="button" id="48151">Click me!</button>
//<p>A paragraph</p>
//<h3>Hello world!</h3>
.redclass {background: red}
<div class="redclass" id="niceid">This is it!</div>
<button class="button" id="48151">Click me!</button>
<p>A paragraph</p>
<h3>Hello world!</h3>
Something like this?
<?php
$html->tag('doctype')->alone('html')->tag();
$html->tag('html')->lang('en');
$html->tag('head');
$html->tag('meta')->charset('utf-8')->tag();
$html->tag('meta')->httpequiv('X-UA-Compatible')->content('IE=edge')->tag();
$html->tag('meta')->name('viewport')->content('width=device-width, initial-scale=1')->tag();
$html->tag('meta')->name('description')->content('Brosta Tools')->tag();
$html->tag('meta')->name('author')->content('Brosta')->tag();
$html->tag('title')->text('Brosta Tools')->tag();
$html->tag('link')->href('assets/plugins/bootstrap/css/bootstrap.min.css')->rel('stylesheet')->tag();
$html->tag('link')->href('assets/plugins/bootstrap/css/simple-sidebar.css')->rel('stylesheet')->tag();
$html->tag('link')->href('assets/plugins/prism/css/prism.css')->rel('stylesheet')->tag();
$html->tag('link')->href('assets/plugins/normalize/css/normalize.css')->rel('stylesheet')->tag();
$html->tag('link')->href('assets/plugins/brosta/css/brosta.css')->rel('stylesheet')->tag();
$html->tag('script')->src('assets/plugins/bootstrap/js/jquery.js')->type('text/javascript')->tag();
$html->tag('script')->src('assets/plugins/bootstrap/js/bootstrap.min.js')->type('text/javascript')->tag();
$html->tag('script')->src('assets/plugins/prism/js/prism.js')->type('text/javascript')->tag();
$html->tag('script')->type('text/javascript')->text('$("#menu-toggle").click(function(e) {e.preventDefault(); $("#wrapper").toggleClass("toggled"); });')->tag();
$html->tag('script')->type('text/javascript')->text('
window.onload = function () {
var x = document.getElementsByClassName("token");
var i;
for (i = 0; i < x.length; i++) {
var variable = x[i].getAttribute("class").replace("token ", "");
var text = x[i].innerText.trim().replace("$", "");
if(!/[^a-zA-Z0-9]/.test(text) || text.indexOf("_") >= 0) {
x[i].className +=" " + variable + "-" + text;
}
}
}
')->tag();
$html->tag();
$html->tag('body')->class('brosta');
$html->include('snippets.brosta.navbar');
$html->tag('div')->class('container-fluid brosta');
$html->tag('div')->id('wrapper');
$html->tag('div')->id('sidebar-wrapper');
$html->tag('ul')->class('sidebar-nav');
$data = [
['link' => '/Instalation', 'text' => 'Instalation'],
['link' => '/Html', 'text' => 'Html']
];
foreach($data as $link)
{
$html->tag('li');
$html->tag('a')->href($link['link'])->text($link['text'])->tag();
$html->tag();
}
$html->tag();
$html->tag();
$html->tag('div')->id('page-content-wrapper');
$html->tag('div')->class('row');
$html->tag('div')->class('col-lg-12');
$html->tag('div')->class('panel panel-default');
$html->tag('div')->class('panel-heading clearfix')->text('Without Time')->tag();
$html->tag('div')->class('panel-body');
$html->tag('p')->text('Make a file in your root public server. Ex: <code class="language-php">C:\xampp\htdocs\index.php</code>')->tag();
$html->tag('pre')->class('language-php');
$html->tag('code')->class('language-php')->text($html->specialChars('views/content.php'))->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
$html->tag();
echo $html->get();
This is a bit late, but I've recently written an object-oriented HTML generator for PHP. It supports nesting.
As an example, this...
$h = new \HTML;
echo $h::div(
'class', 'my-class',
'id', 'my-id',
$h::p(
'class', 'paragraph',
'It was a dark and stormy night, at least according to the beginning of the book.'
)
);
...will create this markup (without spaces between the tags)...
<div class="my-class" id="my-id">
<p class="paragraph">It was a dark and stormy night, at least according to the book.</p>
</div>
Hope you find it useful!
studiowbe/html is the right package for me. It has a sound API, with chaining, and it is enabled on Composer.
$link = new Studiow\HTML\Element("a");
$link->setInnerHTML("Documents")
->setAttribute("href", "/documents")
->addClass("button")
->addClass("button-documents")
->setAttribute('title', "Go to documents");
echo (string) $link; // Outputs Documents
The Tag and Attribute classes are simple to understand and they get the job done.
A simple usage example with a single tag
$div = new Tag("div");
$class = new Attribute("class");
$class->addItem("class_a");
$class->addItem("class_b");
$div->addAttribute($class);
echo $div->build();
/**
* Output:
*
* <div class='class_a class_b'></div>
*/
A more complex usage example with multiple tags
a. Creating tags
$mainDiv = new Tag("div");
$innerDiv = new Tag("div");
$h1 = new Tag("h1");
$h2 = new Tag("h2");
$h3 = new Tag("h3");
b. Creating attributes
$class = new Attribute("class");
$class->addItem("someClass");
$style = new Attribute("style", ";");
$style->addItem("font-color: blue");
$style->addItem("font-size: 10px");
c. Adding attributes
$innerDiv->addAttribute($class);
$h3->addAttribute($style);
d. Adding plain text
$h1->setPlainText("This is header one");
$h2->setPlainText("This is header two");
$h3->setPlainText("This is header three");
e. Adding tags
$innerDiv->addTag($h1);
$innerDiv->addTag($h2);
$mainDiv->addTag($innerDiv);
$mainDiv->addTag($h3);
f. Building tags
echo $mainDiv->build();
/**
* Output (with indentation):
*
* <div>
* <div class='someClass'>
* <h1>This is header one</h1>
* <h2>This is header two</h2>
* </div>
* <h3 style='font-color: blue;font-size; 10px'>
* This is header three
* </h3>
* </div>
*/
Tag class
<?php
final class Tag
{
protected array $innerTags = [];
protected array $attributes = [];
protected string $plainText = "";
protected string $tagName;
public function __construct($tagName)
{
$this->tagName = $tagName;
}
public function addTag(Tag $t)
{
$this->innerTags[] = $t;
}
public function addAttribute(Attribute $a)
{
$this->attributes[] = $a;
}
public function setPlainText(string $plainText)
{
$this->plainText = $plainText;
}
public function build(): string
{
if (empty($this->attributes)) {
$pattern = "<%s%s>%s</%s>";
} else {
$pattern = "<%s %s>%s</%s>";
}
return sprintf($pattern,
$this->tagName,
$this->buildAttributes(),
$this->buildInnerContent(),
$this->tagName
);
}
private function buildAttributes(): string
{
$building = [];
foreach ($this->attributes as $att) {
$building[] = $att->build();
}
return implode(" ", $building);
}
/**
* A Tag cannot have inner tags and plain text at
* the same time
*/
private function buildInnerContent(): string
{
if (empty($this->innerTags)) {
return $this->plainText;
}
return $this->buildInnerTags();
}
private function buildInnerTags(): string
{
$building = "";
foreach ($this->innerTags as $tag) {
$building .= $tag->build();
}
return $building;
}
}
Attribute class
<?php
final class Attribute
{
private string $name;
private array $items = [];
private string $itemSeparator;
public function __construct(string $name, string $itemSeparator = " ")
{
$this->name = $name;
$this->itemSeparator = $itemSeparator;
}
public function addItem(string $item)
{
$this->items[] = $item;
}
public function build(): string
{
$formattedItems = implode($this->itemSeparator, $this->items);
return "{$this->name}='{$formattedItems}'";
}
}

Categories