How to display Homeslider in all pages in Prestashop - module

I'm setting a webshop in Prestashop (1.6.1.1.) using the theme Default-Bootstrap.
I'm using the "Image slider for your homepage" module but it's only displayed in the homepage. I tried different things but any of them worked:
I've removed the condition {if $page_name =='index'}from the /homeslider.tpl
I've tried to force it by using the following condition in header.tpl:
{if $page_name !='index' && $page_name !='pagenotfound'}
{include file="$tpl_dir./modules/homeslider/homeslider.tpl"}
{/if}
I've tried to copy&paste the code from the /homeslider.tpl directly to the header/tpl template but only the <!-- Module HomeSlider -->comments are displayed with anything between (the {if isset($homeslider_slides)} condition seems to return false).
Of course, the module is hooked in the DisplayTop but still nothing happens outside the homepage... and using DisplayTopColumn is not an option.
Here is the code of the homeslider.tpl:
<!--{if $page_name =='index'} -->
<!-- Module HomeSlider -->
{if isset($homeslider_slides)}
<div id="homepage-slider">
{if isset($homeslider_slides.0) && isset($homeslider_slides.0.sizes.1)}{capture name='height'}{$homeslider_slides.0.sizes.1}{/capture}{/if}
<ul id="homeslider"{if isset($smarty.capture.height) && $smarty.capture.height} style="max-height:{$smarty.capture.height}px;"{/if}>
{foreach from=$homeslider_slides item=slide}
{if $slide.active}
<li class="homeslider-container">
<a href="{$slide.url|escape:'html':'UTF-8'}" title="{$slide.legend|escape:'html':'UTF-8'}">
<img src="{$link->getMediaLink("`$smarty.const._MODULE_DIR_`homeslider/images/`$slide.image|escape:'htmlall':'UTF-8'`")}"{if isset($slide.size) && $slide.size} {$slide.size}{else} width="100%" height="100%"{/if} alt="{$slide.legend|escape:'htmlall':'UTF-8'}" />
</a>
{if isset($slide.description) && trim($slide.description) != ''}
<div class="homeslider-description">{$slide.description}</div>
{/if}
</li>
{/if}
{/foreach}
</ul>
</div>
{/if}
<!-- /Module HomeSlider -->
<!--{/if}-->
And a piece of the header.tpl:
<div class="header-container">
<header id="header">
{capture name='displayBanner'}{hook h='displayBanner'}{/capture}
{if $smarty.capture.displayBanner}
<div class="banner">
<div class="container">
<div class="row">
{$smarty.capture.displayBanner}
</div>
</div>
</div>
{/if}
{capture name='displayNav'}{hook h='displayNav'}{/capture}
{if $smarty.capture.displayNav}
<div class="nav">
<div class="container">
<div class="row">
<nav>{$smarty.capture.displayNav}</nav>
</div>
</div>
</div>
{/if}
<div>
<div class="container">
<div class="row">
<div id="header_logo">
<a href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{$shop_name|escape:'html':'UTF-8'}">
<img class="logo img-responsive" src="{$logo_url}" alt="{$shop_name|escape:'html':'UTF-8'}"{if isset($logo_image_width) && $logo_image_width} width="{$logo_image_width}"{/if}{if isset($logo_image_height) && $logo_image_height} height="{$logo_image_height}"{/if}/>
</a>
</div>
{if isset($HOOK_TOP)}{$HOOK_TOP}{/if}
/*********************************************
HERE I'D LIKE TO DISPLAY THE HOMESLIDER MODULE
*********************************************/
<!--{if $page_name !='index' && $page_name !='pagenotfound'}
{include file="$tpl_dir./modules/homeslider/homeslider.tpl"}
{/if} -->
</div>
</div>
</div>
</header>
</div>
I hope I've explained the problem well so you can be able to help me :)
Thanks in advance!
iarcas

I think you're on the right track, you foudn the conditional in templates, but have you checked the actual hook in the module?
See this:
homslider.php
public function hookdisplayTopColumn($params)
{
if (!isset($this->context->controller->php_self) || $this->context->controller->php_self != 'index')
return;
if (!$this->_prepareHook())
return false;
return $this->display(__FILE__, 'homeslider.tpl', $this->getCacheId());
}
So basically, you have to make an override for this function:
/override/modules/homeslider/homeslider.php
<?php
class HomeSliderOverride extends HomeSlider
{
public function hookdisplayTopColumn($params)
{
if (!$this->_prepareHook())
return false;
return $this->display(__FILE__, 'homeslider.tpl', $this->getCacheId());
}
}

Related

Add to cart button doesn't work. After click the button cart page doesn't load

This is Laravel 8.I set '/cart' route to href of add to cart button.but it also didn't work.got an error as 'session not found'.I made this while watching a youtube video.But it's not work.
What is the problem of my code?
Plz help me!
ShopComponent.php
<?php
namespace App\Http\Livewire;
use App\Models\Product;
use Livewire\Component;
use Livewire\WithPagination;
use Cart;
class ShopComponent extends Component
{
public function store($product_id,$product_name,$product_price){
Cart::add($product_id,$product_name,1,$product_price)->asseociate('App\Models\Product');
session()->flash('success_message','Item added in Cart');
return redirect()->route('product.cart');
}
public function render()
{
$products = Product::paginate(12);
return view('livewire.shop-component',['products'=>$products])->layout("layouts.base");
}
}
shop-component.blade.php
<div class="product-info">
<span>{{$product->name}}</span>
<div class="wrap-price"><span class="product-price">{{$product->regular_price}}</span></div>
Add To Cart
</div>
web.php
<?php
use App\Http\Livewire\HomeComponent;
use App\Http\Livewire\ShopComponent;
use App\Http\Livewire\CartComponent;
use App\Http\Livewire\CheckoutComponent;
use App\Http\Livewire\DetailsComponent;
use App\Http\Livewire\User\UserDashboardComponent;
use App\Http\Livewire\Admin\AdminDashboardComponent;
use Illuminate\Support\Facades\Route;
Route::get('/cart',CartComponent::class)->name('product.cart');
app.php
'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
])->toArray(),
DetailsComponent.php
<?php
namespace App\Http\Livewire;
use App\Models\Product;
use Livewire\Component;
use Cart;
class DetailsComponent extends Component
{
public $slug;
public function mount($slug){
$this->slug=$slug;
}
public function store($product_id,$product_name,$product_price){
Cart::add($product_id,$product_name,1,$product_price)->asseociate('App\Models\Product');
session()->flash('success_message','Item added in Cart');
return redirect()->route('product.cart');
}
cart-component.blade.php
<div class=" main-content-area">
<div class="wrap-iten-in-cart">
#if(session::has('success_message'))
<div class="alert alert-success">
<strong>Success</strong>{{Session::get('success_message')}}
</div>
#endif
#if(Cart::count()>0)
<h3 class="box-title">Products Name</h3>
<ul class="products-cart">
#foreach(Cart::content() as $item)
<li class="pr-cart-item">
<div class="product-image">
<figure><img src="{{('assets/images/products')}}/{{$item->image}}" alt="{{$item->model->name}}"></figure>
</div>
<div class="product-name">
<a class="link-to-product" href="{{route('product.details',['slug'=>$item->model->slug])}}">{{$item->model->name}}</a>
</div>
<div class="price-field produtc-price"><p class="price">Rs.{{$item->model->regular_price}}</p></div>
<div class="quantity">
<div class="quantity-input">
<input type="text" name="product-quatity" value="{{$item->qty}}" data-max="120" pattern="[0-9]*" >
<a class="btn btn-increase" href="#"></a>
<a class="btn btn-reduce" href="#"></a>
</div>
</div>
<div class="price-field sub-total"><p class="price">Rs.{{$item->subtotal}}</p></div>
<div class="delete">
<a href="#" class="btn btn-delete" title="">
<span>Delete from your cart</span>
<i class="fa fa-times-circle" aria-hidden="true"></i>
</a>
</div>
</li>
#endforeach
</ul>
#else
<p>No Item In Cart</p>
#endif
</div>

VUE's focus() method return a console error? How to use it correctly?

I'm trying to focus on several elements of my form but the first one, despite being applied, returns an error by console.
This is my template:
<div class="container">
<div class="col-xs-12">
<div class="row">
<h1 class="animal-title">Your selection is : </h1>
</div>
<div class="wrapper">
<form class="first-form" #submit.prevent="onSubmit">
<div class="image-wrapper">
<div class="sel-image">
<div v-on:click="imageSelected = true" v-for="item in items" v-bind:key="item.id">
<label>
<input
type="radio"
name="selectedItem"
ref="item"
:value="item.id"
v-model="itemFormInfo.selectedItem"
#change="onChangeItem($event)"
/>
<img v-if="item.id === 1" src="../../assets/1.png" />
<img v-if="item.id === 2" src="../../assets/2.png" />
<img v-if="item.id === 3" src="../../assets/3.png" />
</label>
<p class="cie-animal-subtitle">{{item.name}}</p>
</div>
</div>
</div>
<div class="form-select">
<div v-show="filteredStock && (imageSelected || itemFormInfo.selectedItem) > 0">
<h1 v-if="this.itemName === 'Phone' || this.itemName === 'Tablet'" for="selectedItem" ref="itemVisible">
Select the brand of your <span>{{this.itemName}}</span> :
</h1>
<h1 v-if="this.itemName === 'PC'" for="selectedBreed" ref="itemVisible">
Select the type of your <span>{{this.itemName}}</span> :
</h1>
<select
ref="brand"
class="form-control"
id="selectedBrand"
v-model="itemFormInfo.selectedBrand"
#change="onChangeBrand($event)">
<option v-for="brand in filteredBrand" v-bind:key="brand.name">{{ brand.name }}</option>
</select>
<div v-show="this.isBrandSelected">
<h1>What are you going to use your
<span>{{itemName}}</span> for ?
</h1>
<input
type="text"
id="componentName"
ref="componentName"
class="form-control fields"
style="text-transform: capitalize"
v-model="itemFormInfo.component"
#keypress="formChange($event)"
/>
<div class="loader-spinner" v-if="loading">
<app-loader/>
</div>
</div>
</div>
</div>
<div class="service-options" v-show="isComponentCompleted">
<div class="from-group">
<h1>
Here are the options for your <span>{{this.itemFormInfo.component}}</span> :
</h1>
<div class="services">
<div class="column-service" v-for="option in options" v-bind:key="option.name">
<div class="service-name">{{option.name}}</div>
<div class="service-price">{{option.price.toString().replace(".", ",")}} </div>
</div>
</div>
and here my first method
onChangeItem(event) {
let item = event.target._value;
this.itemName = this.getItemName(item);
if (this.isItemSelected = true) {
this.isItemSelected = false;
this.isComponentCompleted = false;
this.isLoaderFinished = false;
this.itemFormInfo.name = ""
}
this.$refs.item.focus();
},
in this function that I control my first input, the focus is working but it returns me by console the following error:
"this.$refs.item.focus is not a function at VueComponent.onChangeItem"
I have seen some references to similar cases where they involved the reference in a setTimeout or used the this.$nextTick(() => method but it didn't work in my case.
What am I doing wrong?
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
Thank you all for your time and help in advance
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
You want to put focus on brand but your onChangeItem handler is calling this.$refs.item.focus() (trying to focus item). Seems strange to me...
Reason for the error is you are using ref inside v-for.
Docs: When used on elements/components with v-for, the registered reference will be an Array containing DOM nodes or component instances
So the correct way for accessing item ref will be this.$refs.item[index].focus().
Just be aware that right now v-for refs do not guarantee the same order as your source Array - you can find some workarounds in the issue discussion...

Prestashop: Hide categories without products

I would like to know if there's a way to hide categories whose sub-categories' products are out of stock.
The file with the code to show the categories is "ps_mainmenu.tpl", whose code is attached
Thanks in advance
Ive tried with some modules like "block-categories-with-counter" but it doesn't work
{assign var=_counter value=0}
{function name="menu" nodes=[] depth=0 parent=null}
{if $nodes|count}
<ul class="top-menu top-menu--level-{$depth}" {if $depth == 0}id="top-menu"{/if} data-depth="{$depth}">
{foreach from=$nodes item=node}
<li class="category-custom category-custom--level-{$depth} {$node.type}{if $node.current} current {/if}" id="{$node.page_identifier}">
{assign var=_counter value=$_counter+1}
<a
class="{if $depth >= 0}dropdown-item{/if}{if $depth === 1} dropdown-submenu{/if}"
href="{$node.url}" data-depth="{$depth}"
{if $node.open_in_new_window} target="_blank" {/if}
>
{if $node.children|count}
{* Cannot use page identifier as we can have the same page several times *}
{assign var=_expand_id value=10|mt_rand:100000}
<span class="float-xs-right hidden-md-up">
<span data-target="#top_sub_menu_{$_expand_id}" data-toggle="collapse" class="navbar-toggler collapse-icons">
<i class="material-icons add"></i>
<i class="material-icons remove"></i>
</span>
</span>
{/if}
{$node.label}
</a>
{if $node.children|count}
<div {if $depth === 0} class="popover sub-menu js-sub-menu collapse"{else} class="collapse"{/if} id="top_sub_menu_{$_expand_id}">
{menu nodes=$node.children depth=$node.depth parent=$node}
</div>
{/if}
</li>
{/foreach}
</ul>
{/if}
{/function}
<div class="menu js-top-menu position-static hidden-sm-down" id="_desktop_top_menu">
{menu nodes=$menu.children}
<div class="clearfix"></div>
</div>
You need to remove empty category in the SQL query, so in your php wrap your code with something like that :
$count = Db::getInstance()->getValue('SELECT COUNT(cp.id_category) FROM '._DB_PREFIX_.'category_product cp, '._DB_PREFIX_.'product pr WHERE cp.id_category = '.$id_current_category .' AND cp.id_product = pr.id_product AND pr.active = 1' );
if($count>0)
{
//your actual code to get the category
}

Populate Knockout's observable array from Razor

I'm trying to implement error handling in ASP.NET so that if there is an error the user will get the error message, then be able to go back and have the previous state restored. I'm using ASP.NET Core and Knockout (not my implementation). I want to update "signerFields" with the model from the server (Model.SignersJson). How would I do this?
Signer.js
function SignerViewModel() {
var self = this;
self.signerFields = ko.observableArray([]);
self.guarantorFields = ko.observableArray([]);
self.companyGuarantorFields = ko.observableArray([]);
...
Signer.cshtml
<div data-bind="foreach: signerFields, visible: signerFields().length > 0">
<div class="row">
<div class="col-lg-10">
<div>
#*Header Company signers section*#
<div class="row" data-bind="visible: isCompany() && !anySigner() && !isInvitation()" style="display: none">
<div class="col-lg-4">
<b>FullName</b>
</div>
#*<div class="col-lg-3">
<b>LastName </b>
</div>*#
<div class="col-lg-4">
<b>Role </b>
</div>
<div class="col-lg-3">
<b>Contact_Information</b>
</div>
</div>
</div>
</div>
...
#section scripts
{
<script src="~/Scripts/Signer.js"></script>
var serverSigners = JSON.parse(#Html.Raw(Json.Encode(Model.SignersJson)));
var observableData = ko.mapping.fromJS(serverSigners);
var viewModel = new SignerViewModel();
viewModel.signerFields(observableData); // <-- How?
}
I get no error messages, nothing.
There is a lot of unknowns with this one, but here is a working example using the information we have at hand. One thing I noticed was when creating this sample was that I assumed the data comming from Razor was in an array. and when the array is passed into the mapping component it comes out as an observable array. This meant that the data going into the signerFields was probably not what you were expecting and ended up having an observableArray with one object which itself was an observable array. Adding round brackets to observableData() means that you get the data out of the observable and you can then pass it into the signerFields as an array of objects.
Hope that made sense.
function SignerViewModel() {
var self = this;
self.signerFields = ko.observableArray([]);
self.guarantorFields = ko.observableArray([]);
self.companyGuarantorFields = ko.observableArray([]);
}
var serverSigners = [{'fullname':'Test Name', 'lastName': 'Name', 'role': 'Test Role', 'contactInformation': '123 Seasame Street NY, US', 'isCompany': true, 'anySigner': false, 'isInvitation': false}];
var observableData = ko.mapping.fromJS(serverSigners);
var viewModel = new SignerViewModel();
viewModel.signerFields(observableData());
ko.applyBindings(viewModel)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: signerFields, visible: signerFields().length > 0">
<div class="row">
<div class="col-lg-10">
<div>
<div class="row" data-bind="visible: isCompany() && !anySigner() && !isInvitation()">
<div class="col-lg-4">
<b>FullName: </b><span data-bind="text: fullname"></span>
</div>
<div class="col-lg-3">
<b>LastName: </b><span data-bind="text: lastName"></span>
</div>
<div class="col-lg-4">
<b>Role: </b><span data-bind="text: role"></span>
</div>
<div class="col-lg-3">
<b>Contact Information: </b><span data-bind="text: contactInformation"></span>
</div>
</div>
</div>
</div>
</div>
</div>

display subcategories from category ID - Prestashop 1.7

I'd like to show all subcategory of category on homepage in prestashop 1.7
I was create this functions but it's show only 1 deep child subcategory:
How to set forech all subcategory from category ID 231?
$categories shows only main categories, no subcategories.
{if isset($categories) AND $categories}
<div id="subcategories">
<ul class="clearfix">
{foreach from=$categories item=subcategory name=homeCategories}<li>
<div class="subcategory-image">
<a href="{$link->getCategoryLink($subcategory.id_category, $subcategory.link_rewrite)|escape:'html':'UTF-8'}"
title="{$subcategory.name|escape:'html':'UTF-8'}" class="img">
{if $subcategory.id_image}
<img class="replace-2x"
src="{$link->getCatImageLink($subcategory.link_rewrite, $subcategory.id_image, 'category_default')|escape:'html':'UTF-8'}"
alt="" width="{$mediumSize.width|escape:'htmlall':'UTF-8'}" height="{$mediumSize.height|escape:'htmlall':'UTF-8'}"/>
{else}
<img class="replace-2x" src="{$img_cat_dir|escape:'htmlall':'UTF-8'}{$lang_iso|escape:'htmlall':'UTF-8'}-default-medium_default.jpg"
alt="" width="{$mediumSize.width|escape:'htmlall':'UTF-8'}" height="{$mediumSize.height|escape:'htmlall':'UTF-8'}"/>
{/if}
</a>
</div>
<h5><a class="subcategory-name"
href="{$link->getCategoryLink($subcategory.id_category, $subcategory.link_rewrite)|escape:'html':'UTF-8'}">{$subcategory.name|truncate:60:'...'|escape:'html':'UTF-8'}</a>
</h5>
</li>{/foreach}
</ul class="clearfix">
</div>
{else}
<p>{l s='No categories' mod='homecategories'}</p>
{/if}