Quantcast
Channel: Webkul Blog
Viewing all articles
Browse latest Browse all 5537

Add Position column in the render list in Prestashop/QloApps

$
0
0

In this blog, We will learn the process to implement position in the render list column.

Prestashop has predefined steps to implement the position column and you can manage positions from the render list with the drag and drop feature.

First of all, see in the below image what we are going to implement.

So we will implement the position column in the above image and learn the process to manage it.

Keywords used in blog :

We will use some keywords in the pieces of code used for the explanations in this blog. I am describing them below –

  1. your_table_name: This the name of the database table in which the position column is created for the learning of the positioning process.
  2. id_primary_key: This the primary key of table your_table_name.
  3. YourClassName: This the name of the class which is created for the table for which we are implementing the render list.

Lets start the process step by step.

Steps 1 :

You have to create a column with name “position” in the table for which render list is created.

`position` int(10) unsigned NOT NULL DEFAULT '0',

Steps 2 :

Specify the Identifier in admin controller to use for changing positions in list.

protected $position_identifier = 'id_primary_key';
// id_primary_key is the primary key in the table you have to change with the primary key of your table

In this step, you have to specify the identifier variable ($position_identifier) according to which positions in the render list will be changed with the drag and drop feature. So we have used the primary key of the table as the position identifier.

You can skip this step if you don’t wat to change the positions with drag and drop feature in render list.

Steps 3 :

In your admin controller, In the __construct() method write the position column information array in the $this->fields_list property

$this->fields_list = array(
    'id_table' => array(
        'title' => $this->l('ID'),
        'align' => 'center',
    ),
	.
	.
	.            
    'position' => array(
        'title' => $this->l('Position'),
        'filter_key' => 'a!position',
        'position' => 'position',
        'align' => 'center',
    ),
    .
    .
    .
);

You have to declare special key position for the position type column. see the position array carefully.

So, After these above steps, Your position column will be visible in your render list with the drag and drop feature.

Now, we have to manage two test cases for the proper management of the position column working.

  • When we change position from the render list then update the position in the database.
  • When we delete a row from render list (or through any way) then reset the positions in the database

So lets move further for implementing above points.

Steps 4 :

Update the position in the database when we change position from render list

Whenever you change the position of a row in the render list. Prestashop internally fires an ajax for updating the position of the row. This sends you

  • The value of id (table’s id which you are dragging)
  • The way (up/down) of positioning
  • The array of positions in the render list

For this, you have to implement the ajaxProcessUpdatePositions() function in the admin controller in which you are implementing the position column in the render list.

// update positions with drag and drop in render list
public function ajaxProcessUpdatePositions()
{
    $way = (int) Tools::getValue('way');
    $id = (int) Tools::getValue('id');
    $positions = Tools::getValue('primary_key');

    foreach ($positions as $position => $value) {
        $pos = explode('_', $value);

        if (isset($pos[2]) && (int) $pos[2] === $id) {
            if ($objYourClass = new YourClassName((int) $pos[2])) {
                if (isset($position)
                    && $objYourClass->updatePosition($way, $position, $id)
                ) {
                    echo 'ok position '.(int) $position.' for render list '.(int) $pos[1].'\r\n';
                } else {
                    echo '{"hasError" : true, "errors" : "Can not update position '.
                    (int) $id.' to position '.(int) $position.' "}';
                }
            } else {
                echo '{"hasError" : true, "errors" : "This render list ('.(int) $id.
                ') can t be loaded"}';
            }
            break;
        }
    }
}

In the above code, we are getting positions in the variable $positions.

Here primary_key is used only for an example. In your controller will get it from different key.

For example : If your $this->identifier in the admin controller is id_primary_key then this key will be primary_key (after removing _id from the identifier).

In the above code at line-15, we have called function updatePosition() which you have to implement in your class which is created for the table we implementing render list for.

So in the class, YourClassName write below function –

public function updatePosition($way, $position)
{
    if ($result = Db::getInstance()->executeS(
        'SELECT `id_primary_key`, `position` FROM `'._DB_PREFIX_.'your_table_name` 
        WHERE `id_primary_key` = '.(int) $this->id.' 
        ORDER BY `position` ASC'
    )) {
    	// check if dragged row is in the table
	    $movedBlock = false;
	    foreach ($result as $block) {
	        if ((int)$block['id_primary_key'] == (int)$this->id) {
	            $movedBlock = $block;
	        }
	    }

	    if ($movedBlock === false) {
	        return false;
	    }

	    // set positions in the table
	    return (Db::getInstance()->execute(
	        'UPDATE `'._DB_PREFIX_.'your_table_name` SET `position`= `position` '.($way ? '- 1' : '+ 1').
	        ' WHERE `position`'.($way ? '> '.
	        (int)$movedBlock['position'].' AND `position` <= '.(int)$position : '< '
	        .(int)$movedBlock['position'].' AND `position` >= '.(int)$position)
	    ) && Db::getInstance()->execute(
	        'UPDATE `'._DB_PREFIX_.'your_table_name`
	        SET `position` = '.(int)$position.'
	        WHERE `id_primary_key`='.(int)$movedBlock['id_primary_key']
	    ));
    }
    return false;
}

Steps 5 :

Reset the positions in the database When we delete a row from render list (or through any way)

For this, you have to override the delete function in the class created for the table in which the position the field is implemented.

So in the delete() function call the function which you have created for Reinitializing positions in the table. In our case, we have created function cleanPositions(). So we will call this function created in the same class.

public function delete()
{
    $return = parent::delete();
    /* Reinitializing position */
    $this->cleanPositions();
    return $return;
}

Now lets reinitialize the positions in the function cleanPositions().

/**
 * Reorder positions in the table
 * Call it after deleting a row in the table.
 * @return bool
*/
public function cleanPositions()
{
    Db::getInstance()->execute('SET @i = -1', false);
    $sql = 'UPDATE `'._DB_PREFIX_.'your_table_name` SET `position` = @i:=@i+1 ORDER BY     `position` ASC';
    return (bool) Db::getInstance()->execute($sql);
}

So these are few simple steps through which you can implement and manage the position field/column working in your render list.

So I hope it will help you somewhere while coding in Prestashop.

Happy coding. 🙂


Viewing all articles
Browse latest Browse all 5537

Trending Articles