Prestashop: how to display messages in the cart - smarty

i'm working in a quota module for PrestaShop 1.6 and in one of the features is that a need to display a message in the cart's page and in that modal that opens when you add an item to the cart from the home page.
I'm working with the hookCart the hook function, public function hookCart($params), is in my module's class. From it I can get the instance of the Controller like this $this->context->controller
My question is how to display messages in these two views? I tried adding them to the errors array. I can see the message but not the way I'm supposed to display. I would like to display in those alert classes from bootstrap.
The views:
Can you help me?

To display a message on the checkout page you can use whatever front controller hook you want. I guess the one that makes most sense would be displayTop. We won't be outputting any html to the top but just add a message to the controller's errors array.
public function hookDisplayTop()
{
$controller = $this->context->controller;
if ($controller->php_self != 'order' && $controller->php_self != 'order-opc') {
return false;
}
/*
You can do custom logic here if you want to display message only
on some conditions or only on specific step of the checkout
*/
$controller->errors[] = $this->l('Some message');
return false;
}
For the popup the things get messy because:
Popup doesn't have an error display area
Blockcart AJAX uses weird logic that calls CartController which includes blockcart-ajax.php which loads blockcart module method which loads a JSON template file to output data (???)
One way to do this is to use the hook actionCartSave. This hook gets executed on pretty much all cart operations, so we need to make sure we are adding our message when a product is added to cart, uses ajax etc.
public function hookActionCartSave()
{
// If cart doesn't exist or product is not being added to cart in ajax mode - do nothing
if (!$this->context->cart || !Tools::getValue('id_product) || !Tools::getValue('add') || !Tools::getValue('ajax')) {
return false;
}
/*
You can do custom logic here if you want to display message only
on some conditions
*/
$this->context->smarty->assign('mycartpopupmessage', $this->l('Message');
return false;
}
Then you will have to modify themes/default-bootstrap/modules/blockcart/blockcart-json.tpl file to add your message into JSON template.
...
"wrappingCost": {$wrapping_cost|json_encode},
"nbTotalProducts": {$nb_total_products|intval},
"total": {$total|json_encode},
{if isset($mycartpopupmessage)}
"mycartpopupmessage": {$mycartpopupmessage|json_encode},
{/if}
....
Then you need to modify themes/default-bootstrap/js/modules/blockcart/ajax-cart.js and add the following
if (jsonData.mycartpopupmessage) {
$('#layer_cart .alert-message').html(jsonData.mycartpopupmessage);
$('#layer_cart .alert').removeClass('hidden');
}
else {
$('#layer_cart .alert').addClass('hidden');
}
And at last modify themes/default-bootstrap/modules/blockcart/blockcart.tpl
and add alert div
<div class="alert alert-danger hidden">
<button data-dismiss="alert" type="button" class="close">×</button>
<p>{l s='There is 1 error' mod='mymodule'}</p>
<ol>
<li class="alert-message"></li>
</ol>
</div>
Now you should be getting a bootstrap alert inside a popup.
Quite some native prestashop modules haven't been (I guess) updated in years as a lot of them are good candidates for an extensive rework or at least compliant with the MVC workflow which would make modifications like yours much more simple.

Related

laravel backup raising 404 to return a view

In short what is happening is, when I try to access a route, Laravel shows a 404 error, with a short description "Page not Found, No query results for model [App\Models\Product] teste ".
Inside of my model I have the method "teste" which invokes a route.
public function teste($crud = false)
{
return '<a class="btn btn-xs btn-default" href="product/teste" data-toggle="tooltip" title="Just a demo custom button."><i class="fa fa-search"></i> Add Item</a>';
}
button image in the datatable line
Adding a button inside of ProductCrudController
$this->crud->addButton('top', 'bteste', 'model_function', 'teste', 'beginning');
Inside of custom.php I have tried already:
CRUD::resource('product/teste', 'ProductCrudController#teste');
Route::get('product/teste', 'ProductCrudController#teste');
Inside of my Controller I have my method named teste
public function teste(){
return view('vendor/backpack/crud/teste');
}
And finally inside of this path I have my view "which is pretty simple" and only retues a simple hello.
What is the purpose
I need to build a form which allows the user to add "a component" for the product once that the product is always customized. This means, a combination of components makes up a new product.
What I need is: Add a new button in the product line which when clicked gonna redirect the user to add all components which makes up this product. Same idea of an order which contain items.
I could not find by myself the possible options to fit my need.
Is that possible to be done by backpack? If so is there any example to be followed?
Thanks

How to disable cart page from showing coupon notice when adding coupons with ajax?

I am adding coupons in woocommerce programmatically, and is working quite fine via ajax from another page, not the checkout page. However, everytime I go to the checkout page, it says, "Coupon has been applied", but I already applied the coupon from a different page. How do I disable this message from showing when going to the checkout page, after I have performed my ajax for applying a coupon dynamically? Is there some sort of setting or function to call to disable this message from showing on the cart page when a coupon has already been applied from an ajax function?
Here's my php for applying the coupon via ajax from a separate page (not the checkout page):
if (!WC()->cart->add_discount( sanitize_text_field( $coupon_code )))
{
$notices = wc_get_notices();
if (!empty($notices) && isset($notices['error'])) {
$last_fail = end($notices['error']);
echo $last_fail;
}
die();
}
else
{
$notices = wc_get_notices();
// Get last element of array only!
if (!empty($notices) && isset($notices['success'])) {
$last_success = end($notices['success']);
echo $last_success;
}
die();
}
And this works fine. As you can see, I grab errors and have them returned within the response of the ajax call, and output errors that way. I also output something for success, which is fine. The problem I'm having is that after this function executes via ajax, and I browse to the checkout page to see my product and coupon code that was applied, it puts notice at the top of the page, saying "Coupon applied Successfully." and I don't want this notice to appear, but I don't want to get rid of all notices, just this one, if the coupon was not applied on the checkout page, there is no need for this wc_notice to appear when browsing to the checkout page.
How to tell woocommerce not to apply this coupon notice to the checkout page when I browse to the checkout page after adding coupons manually from another page (via ajax)?
You can use the "woocommerce_coupon_message" filter to hide the success message for the coupon. As you want to remove it for checkout page only, just check if current page is checkout page or not.
You can use the following code :
function remove_msg_filter($msg, $msg_code, $this){
if(is_checkout()){
return "";
}
return $msg;
}
add_filter('woocommerce_coupon_message','remove_msg_filter',10,3);
Note : If you also want to change message for error then use "woocommerce_coupon_error" filter.
The way to fix this is to add wc_clear_notices(); before die(); in the function call, so as to remove all notices that the function add_discount adds to the array that gets returned from wc_get_notices() function call.
if (!WC()->cart->add_discount( sanitize_text_field( $coupon_code )))
{
$notices = wc_get_notices();
if (!empty($notices) && isset($notices['error'])) {
$last_fail = end($notices['error']);
echo $last_fail;
}
wc_clear_notices();
die();
}
else
{
$notices = wc_get_notices();
// Get last element of array only!
if (!empty($notices) && isset($notices['success'])) {
$last_success = end($notices['success']);
echo $last_success;
}
wc_clear_notices();
die();
}
This way may be a bit of a lazy way of approaching this. But if you inspect element of the page, find the message, target it and add 'display:none;' in the CSS.
That should do the trick. Try and make it specific for that page only. A unique class is usually page-id found at the top of the page in inspect element

client side validation not working for model window / ajax-loaded-form in yii

I am using Yii-user extension in the main layout i have a sign up link which is common to all the Cmenu
view/main layout
echo CHtml::link('Signup','#',array('id'=>'regi'));
$("#regi").click(function(){
$.ajax({
type:'GET',
url:'<?php echo Yii::app()->request->baseUrl;?>/index.php/user/registration',
success:function(res){
$("#dispdata").show();
$("#dispdata").html(res);
}
});
});
<div id="dispdata"><div>
**yii user extension **renders this perfectly and even submit its correctly if form values a re valid.
but if the values are incorrect and blank it redirect to url .../user/registration
which is not what my need .I need guidance what do i do such that if the values are incorrect or blank it should not redirect and display the errors in model window.
I did tried but hardly could get the satisfied results
if i place the following the model window itself doesnt appear what do i do
module registrationController i placed
....//some code here (**in yiiuser register controller**)
if ($model->save()) {
echo CJSON::encode(array(
'status'=>'success',
));
}
....//some code here...
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
$this->renderPartial('registration',array('model'=>$model,),false,true);
in module view registration
<?php echo CHtml::ajaxSubmitButton(Yii::t('registration'),CHtml::normalizeUrl(array('user/registration','render'=>false)),array('dataType'=>'json',
'success'=>'function(data) {
if(data != null && data.status == "success") {
$("#registration-form").append(data.data);
}
}')); ?>
can anyone please guide me am working past 10 ten days tried every hook or crook method but could not obtain the results......how can the model window with client side validation be done appear..... Please guide me or let me know something better can be done
rules in registration model
if (!(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')) {
array_push($rules,array('verifyCode', 'captcha', 'allowEmpty'=>!UserModule::doCaptcha('registration')));
as well was not with attributes for reqired field
have changed to
array_push($rules,array('verifyCode', 'captcha','message' => UserModule::t("captcha cannot be blank.")));
and added the verifycode to required field
yet not working,
The simple way is using render method in your Ajax action and creating empty layout for this action. If you do so, validation scripts will be included in the server response. Also you need to exclude jquery.js and other script with Yii::app()->clientScript->scriptMap and include them in main layout always.

zend framework display/process form using same action/view?

Using MVC architecture (Zend Framework), should you use a single view with if statements to display/process a form, or multiple views (i.e. one view to display form, one to display result).
In this instance, I am trying to produce a google like search engine. The layout of the page will fundamentally change when displaying search results.
For example; Controller:
public function indexAction()
{
if (!$this->getRequest()->isPost()) {
// display form
} else {
if ($this->_request->isPost()) {
if (!$form->isValid($formData)) {
// re-display form with errors
} else {
// process form and;
// display result using same action/view?
// display result using same action but use a different view?
}
}
}
}
Using the same view:
<?php if(isset($this->form)) : ?>
<!-- show form -->
<?php else: ?>
<!-- show result -->
<?php endif; ?>
Hope that makes sense.
Don't get caught up in the old monolithic style of coding where one hunk of code does everything for one output page. The whole point of MVC is so separate responsibility. Think of a view as a template for a single piece of output, regardless of what page/url it appears on. The form is one piece of output. The search results is another. Use two views.
Less if-s -- less bugs. I propose you to use more different views here, that can reuse one form.

Help needed on running a MYSQL script in the background of a web page and taking different actions dependent on the result

I have a form on a web page, with one field to enter a code, to search for a property.
On clicking 'submit' I want to be able to run a script in the background without leaving the page.
The script will need to run a MYSQL statement which will have one of these results:
The property code does not exist, so display a Javascript Alert saying it does not exist.
The property is for sale, so call an existing javscript function 'saleSubmit(propertyCode)' to overwrite the exsiting web page with a new page sale.php for that property code
The property is for rent, so call an existing javscript function 'rentSubmit(propertyCode)' to overwrite the exsiting web page with a new page rent.php for that property code
The property is for sale and rent, so display 2 checkboxes within a div on the page to choose either the sales details or the rental details.
Can anybody point me in the right direction here?
Hi Nick - I think I screwed the system up a bit as I initially posted a question, then created an account which would not let me comment on the thread.
The status of the query is as simple as: does not exist, sale, rent, sale & rent
Extra advice would be really appreciated as I am problems googling for examples or a tutorial to point me in the right direction.
I first took this approach when I was looking at this problem to check that the form and Select statement were working correctly. So my form code looked like this:
<form name="idsearch" action="" method="post" onsubmit="xmlhttpPostForm('includes/idsearch-response.php', 'idsearch', 'idSearchResult', '<img src=\'images/loading.gif\'>'); return false;">
<input type="text" id="idRefNo" name="idRefNo" value="Enter Property Code" onfocus="this.value='';" />
GO <input type="image" src="img/template/search2.gif" alt="Click to Search for Properties"/>
and the php code called looked like this:
$idRefNo = $_POST['idRefNo'];
$query = "SELECT DISTINCT * FROM property WHERE property.Title = '".$idRefNo."' AND suspend != 'Yes'"; $result = #mysql_query ($query);
if ($result) { // If the query runs ok
if ($result != "") {
while ($row = mysql_fetch_array ($result, MYSQL_ASSOC)) {
if ($row["BaseRental"] > 0 AND $row["Saleprice"] > 0) {
echo 'This property is for RENT and for SALE <br/>';
} else if ($row["BaseRental"] > 0) {
echo 'This property is for RENT only <br/>';
} else if ($row["Saleprice"] > 0) {
echo 'This property is for SALE only <br/>';
} else {
echo 'DOH! What is going on here!!! <br/>';
}
}
As I said above I would appreciate it if you could point me in the right direction to achieve what I want to do at the beginning of this thread.
First of all let's differentiate between the page(client) and your mysql database(server). Your page will have to send some request to your server which triggers a script to query the database. The result of that query is returned as a response to your page.
You could send a request by using javascript and the xmlhttprequest or try jquery which offers very simple methods to make requests ($.ajax(...)).
Your server and the script which queries your db should then return some meaningful status back to your client which has to interprete the result: Doing alerts, showing your div or whatever you'd like to do. I suggest returning the response as json which can be directly used in javascript without any parsing hassle. If the status of your query as simple as: does not exist, sale, rent, sale & rent. You could go as far and encode those as plaintext numbers, no json needed.

Resources