Jump to content

Repeatable fields in category form


Recommended Posts

Hi, I need to create repeating fields in the category form. So in the category form I have an 'Add fields' button and after the ajax request, new fields are given to me. The fields I need are text input and RTE (text editor).
Is it possible to do?
I'm only interested in a PHP function that would return these fields

Link to comment
Share on other sites

What you need is:
1. javascript that will be executed in the AdminCategories controller via actionAdminControllerSetMedia
2. php file for ajax processing
3. function in your module
4. tpl template into which you will load data
5. your own database table where you will store data

It would take a long time to list everything here, and I doubt that anyone will give you the complete solution here.

sample ajax.js:

function parseBetween(beginString, endString, originalString) {
    var beginIndex = originalString.indexOf(beginString);
    if (beginIndex === -1) {
        return null;
    }
    var beginStringLength = beginString.length;
    var substringBeginIndex = beginIndex + beginStringLength;
    var substringEndIndex = originalString.indexOf(endString, substringBeginIndex);
    if (substringEndIndex === -1) {
        return null;
    }
    return originalString.substring(substringBeginIndex, substringEndIndex);
}

function readAjaxContent(){
	var url = window.location.href;
	var getIdcategoryFromUrl = parseBetween('categories/', '/edit', url);
	$.ajax({
		type: "POST",
		url: my_module_content_ajax
		data: 'idCategory'+dgetIdcategoryFromUrl,
		dataType: "html",
		crossDomain: true,
		async: true,
		success: function(response){
			$('#my-custom-id-div').html(response);
		},
	});
}

 

sample ajax.php:

header("Access-Control-Allow-Origin: *");

include('../../../config/config.inc.php');
include('../../../init.php');

$module_name = 'my_module';

$token = pSQL(Tools::encrypt($module_name.'/ajax.php'));
$token_url = pSQL(Tools::getValue('token'));

$module = Module::getInstanceByName($module_name);

if ($token != $token_url || !Module::isInstalled($module_name)) {
    echo($module->l('Ajax error'));
}


if ($module->active) {
    $result = $module->getCustomAdminCategoryTpl(Tools::getValue('idCategory'));
    echo $result;
}

 

sample module function:

    public function getCustomAdminCategoryTpl($params)
    {
        $this->templateDisplayCategoryPage = _PS_MODULE_DIR_.$this->name.'/views/templates/admin/category.tpl';

        $idCategory = $params;

        if (!$idCategory){return;}

        $getSavedData = Db::getInstance()->execute('SELECT * FROM '._DB_PREFIX_.'my_custom_table WHERE id_category = '.$idCategory);

        $categoryData = array();

        foreach ($getSavedData as $data){
            $categoryData[] = array('id_category' => $data['id_category'], 'text_field' => $data['textfield'], 'textarea' => $data['textarea']);
        }

        $this->context->smarty->assign('category_data', $categoryData);


        if (isset($page)) {
            return $this->fetch($this->templateDisplayCategoryPage);
        } else {
            return $this->fetch($this->templateDisplayCategoryPage);
        }
    }

    public function hookActionAdminControllerSetMedia($params)
    {   
        if ($this->active != 1) {return;}

        if (Tools::getValue('controller') == 'AdminCategories') {

            $ajax = $this->context->shop->getBaseURL(true).'modules/'.$this->name.'/ajax/ajax.php?token='.Tools::encrypt($this->name.'/ajax.php');

            Media::addJsDef(
                array(
                    'my_module_content_ajax' => $ajax,
                ),
            );

            $this->context->controller->addJS(_PS_MODULE_DIR_.$this->name.'/views/js/ajax.js');

        }
    }

 

  • Like 1
Link to comment
Share on other sites

Hey, thank you for your reply :)

As i've said early, I'm only interessed in sample module function: because I don't know how to return rendered fields. 

Your example makes sense but it didn't render RTE field (field responsible for creating html, as you have it in the product description, product short description, category description). Your example gives only textarea. And my problem is that I don't know how to initialize RTE field from textarea. 

Link to comment
Share on other sites

TPL sample for one language:

<div class="form-group">
	<div class="col-lg-9">
		<div class="input-group">
			<textarea name="textarea_name" id="textarea_id" class="rte autoload_rte">{$textarea}</textarea>
		</div>
	</div>
</div>
<script type="text/javascript">
    $(document).ready(function(){
		{block name="autoload_tinyMCE"}
			tinySetup({
				editor_selector :"autoload_rte"
			});
		{/block}
	});
</script>

 

  • Like 1
Link to comment
Share on other sites

sample module function:

public function renderTextarea($idCategory)
{
    $languages = Language::getLanguages(false); 
    if ($this->active != 1) {return;}
    $db = Db::getInstance();

    $content = array();
    $idLang = $this->context->language->id;

    $tinyMce = '';

    $l = new Language($this->context->language->id);

    $getSavedData = $db->execute('SELECT * FROM '._DB_PREFIX_.'my_custom_table WHERE id_category = '.$idCategory);

    $tiny_mce = "tinySetup({editor_selector :\"autoload_rte\",setup : function(ed) {ed.onInit.add(function(ed){});ed.onKeyUp.add(function(ed, e) {tinyMCE.triggerSave();textarea = $('#'+ed.id);});}});";

    $tinyMce = "<".base64_decode('c2NyaXB0').">var iso = '" . (Tools::file_exists_cache(_PS_ROOT_DIR_ . '/js/tiny_mce/langs/' . $l->iso_code . '.js') ? $l->iso_code : 'en') . "'; var pathCSS = '" . _THEME_CSS_DIR_ . "'; var ad = '" . __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) . "';$(function() {$tiny_mce});</".base64_decode('c2NyaXB0').">";

    $textarea = '<div class="translations tabbable" id="form_step1_'.$box['field_name'].'">';
    $textarea .= '<div class="translationsFields tab-content">';

    foreach ($languages as $langs) {
        $value = '';
        $value = $db->getRow('SELECT * FROM '._DB_PREFIX_.'my_custom_table  WHERE id_category = '.$idCategory.' AND id_lang = '.$langs['id_lang']);
        $textarea .= '<div data-locale="'.$langs['iso_code'].'" class="translationsFields-form_step1_'.$value['field_name'].'_1 tab-pane translation-field translation-label-'.$langs['iso_code'].' show active">';
        $textarea .= '<textarea class="autoload_rte" name="'.$box['field_name'].'_text_'.$langs['id_lang'].'" cols="100" rows="5">';
        $textarea .= Tools::getValue($value['field_name'].'_text_'.$langs['id_lang'], $value['textarea']);
        $textarea .= '</textarea></div>';
        $description = '<small class="form-text text-muted text-right"><span class="currentLength">';
        $description .= $value['field_description'].'</span></small><br />';
    } 
    
    $textarea .= '</div></div>'; 
    $content[] = '<div class="summary-description-container"><h2>'.$value['field_caption'].'</h2><div class="mb-3">'.$textarea.'</div></div>'.$description;}
    
    $tinyMce .= implode('',$content);
    
    return $tinyMce;
}

public function getCustomAdminCategoryTpl($params)
{
    $this->templateDisplayCategoryPage = _PS_MODULE_DIR_.$this->name.'/views/templates/admin/category.tpl';

    $idCategory = $params;

    if (!$idCategory){return;}

    $getSavedData = Db::getInstance()->execute('SELECT * FROM '._DB_PREFIX_.'my_custom_table WHERE id_category = '.$idCategory);

    $categoryData = array();

    foreach ($getSavedData as $data){
        $categoryData[] = array(
            'id_category' => $data['id_category'], 
            'text_field' => $data['textfield'], 
            'textarea' => $this->renderTextarea($idCategory)
        );
    }

    $this->context->smarty->assign('category_data', $categoryData);

    if (isset($page)) {
        return $this->fetch($this->templateDisplayCategoryPage);
    } else {
        return $this->fetch($this->templateDisplayCategoryPage);
    }
}

 

  • Like 1
Link to comment
Share on other sites

1. I created file form.html.twig inside modules\my_modle\views\PrestaShop\Admin\Sell\Catalog\Categories\Blocks

2. I extended {% block category_form_rest %} {{ parent() }} <my_custom_html> {/block} to make the custom HTML appear

And now I'm stuck because I don't know how can I pass custom variables to my form.html.twig file

Link to comment
Share on other sites

But my question was how can I pass variables to my twig file - not how to display them.

So what is the other way to display custom HTML on category edit page? Because I can only see one hook (displayBackOfficeCategory), which allow me to insert custom html without using twig.

Link to comment
Share on other sites

Omg.

Multi array:

$this->context->smarty->assign(
    array(
        'myArray' => 
            array(
                'myValue' => $myValue,
                'myValue2' => $myValue2
           ),
      )
);

/* twig: {{ myArray.myValue }} and {{ myArray.myValue2 }} */

 

Simple array:

$this->context->smarty->assign('myValue', $myValue);

/* twig  {{ myValue }} */

or

$this->context->smarty->assign(array('myValue' => $myValue, 'myValue2' => $myValue2));

/* twig {{ myValue }} and {{ myValue2 }} */

 

quote:

You need to use smarty just like with the tpl template, only with the difference of two brackets and without the dollar sign.

Edited by 4you.software (see edit history)
  • Like 1
Link to comment
Share on other sites

I'm not getting angry, I'm just tired of repeating what I've already written.

You didn't write what you can program, whether you studied the dev documentation for Prestashop, etc.

https://devdocs.prestashop-project.org/

There are not many programmers here who can advise in more complex situations and give detailed codes.

There is a gray heart under the post for effort or thanks.

Edited by 4you.software (see edit history)
  • Like 1
Link to comment
Share on other sites

Hi.
As @4you.software wrote.
You need to create your own database table in which the values are written.
You also need to add information if the new text and texarea fields are created only once, or if two more fields are created each time the button is clicked.
Where will the fields be created, under which element on the page?
If at the very bottom, just use the classic hookActionCategoryFormBuilderModifier.
Everything you need can be created in this hook.
However, it is worse to delete these fields, or to add, for example, a delete button to them. Another disadvantage is that after clicking the "add field" button, input information must be filled in, namely the field name, field type, default value, etc.

Complete your part of the code that you have already completed so that you can be advised more precisely and attach an image where you want to have the button and the generated field.
It looks like you want the community to program the whole module for you.

Link to comment
Share on other sites

Quote

It looks like you want the community to program the whole module for you.

As I've said - i just needed a php code for returning repeatable RTE field. Where did I ask for all the code? Before asking you guys on forum, I already had created database, extended default category formbuilder and JS with ajax request. I thought there would be some proper way to return input, rather than hardcoding it in tpl file (or twig file). 

Anyway, I have finished my module, I have added buttons to delete each row. Everything works pretty well. 

And btw The published code of the first person did not work so I didn't even want to ask or force to correct it because this would be the reaction 'you want them to do for you'

I think we can close the topic. Thank you guys for helping me out :) I appreciate it

Edited by Piotr3qx (see edit history)
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...