Core: Adding one row with two button in inlinekeyboard

Created on 24 Nov 2017  路  16Comments  路  Source: php-telegram-bot/core

Hi
This code add a row with one key:

$inlineKeyboard = new InlineKeyboard([]);
        foreach ($categories as $cat) {
            $inlineKeyboard->addRow(new InlineKeyboardButton([
                'text'          => $cat['name'],
                'callback_data' => $cat['id'],
            ]));
        }

But how can I add one row with two keys?
I tried:

for ($i=0; $i < count($categories); $i++) { 
            $inlineKeyboard->addRow(new InlineKeyboardButton(
                    [
                        'text'          => $categories[$i]['name'],
                        'callback_data' => $categories[$i]['id'],
                    ], [
                        'text'          => $categories[$i+1]['name'],
                        'callback_data' => $categories[$i+1]['id'],
                    ]
            ));
        }

AND

for ($i=0; $i < count($categories); $i++) { 
            $inlineKeyboard->addRow(new InlineKeyboardButton(
                [
                    [
                        'text'          => $categories[$i]['name'],
                        'callback_data' => $categories[$i]['id'],
                    ], [
                        'text'          => $categories[$i+1]['name'],
                        'callback_data' => $categories[$i+1]['id'],
                    ]
                ]
            ));
        }

AND
for ($i=0; $i < count($categories); $i++) { $inlineKeyboard->addRow(new InlineKeyboardButton( [ 'text' => $categories[$i]['name'], 'callback_data' => $categories[$i]['id'], ] ), new InlineKeyboardButton( [ 'text' => $categories[$i+1]['name'], 'callback_data' => $categories[$i+1]['id'], ] )); }
But none of them works. Any help?

Most helpful comment

Just add it to the keyboard after my code above 馃憤

...
$reply_markup = new InlineKeyboard(...$rows);
$reply_markup->addRow(new InlineKeyboardButton([
    'text'          => '馃敊 袧邪蟹邪写',
    'callback_data' => 'category_' . end($cats)['parent_id'],
]));

All 16 comments

```php
$kb = new InlineKeyboard(
[ // row #1
['text'=>'r1b1', 'callback_data' => 'r1b1'], // row #1, button #1
['text'=>'r1b2', 'callback_data' => 'r1b2'] // row #1, button #2
],
[ // row #2
['text'=>'r2b1', 'callback_data' => 'r2b1'], // row #2, button #1
]
);

Thanks but, I want to know how can I do that in a loop like the first code. Suddenly right now I found the solution!

for ($i=0; $i < count($categories) - 1; $i+=2) { 
            $inlineKeyboard->addRow(new InlineKeyboardButton(
                [
                    'text'          => $categories[$i]['name'],
                    'callback_data' => $categories[$i]['id'],
                ]
            ),
            new InlineKeyboardButton(
                [
                    'text'          => $categories[$i+1]['name'],
                    'callback_data' => $categories[$i+1]['id'],
                ]
            ));
        }

Actually I just miss the minus one!

@Daniyal-Javani Hi! Thanks for your answer. But, I have a similar problem.
My categories displaying from database, and can be dynamically added.

If here are 4 rows in table, my inline keyboard looks like this:
[Button, Button] [Button, Button]

But! If I have 5 rows, buttons look the same as written above. Last row not display.
And I need that:
[Button, Button] [Button, Button] [Button]

I tried to use this:

for ($i=0; $i < count($cats) - 1; $i+=2) {
    if ($i % 2 == 0) {
        $keyboard->addRow(new InlineKeyboardButton([
                    'text' => $cats[$i]['name'],
                    'callback_data' => $cats[$i]['id'],
                ]),
        new InlineKeyboardButton([
                    'text' => $cats[$i + 1]['name'],
                    'callback_data' => $cats[$i + 1]['id'],
                ])
        );
    } else {
            $keyboard->addRow(new InlineKeyboardButton([
                    'text' => $cats[$i]['name'],
                    'callback_data' => $cars[$i]['id'],
            ]));
    }
}

Thanks in advance!

@MyZik There is a much nicer solution for this, which is totally dynamic and has no code duplication! (It requires at least PHP 5.6 though)

$items = array_map(function ($cat) {
    return [
        'text'          => $cat['name'],
        'callback_data' => $cat['id'],
    ];
}, $cats);

$max_per_row  = 2; // or however many you want!
$per_row      = sqrt(count($items));
$rows         = array_chunk($items, $per_row === floor($per_row) ? $per_row : $max_per_row);
$reply_markup = new InlineKeyboard(...$rows);

@noplanman thank you a lot!

But I have a little problem:
If I use foreach, i can easily add "Back" link:

$cats = DB::getPdo()->query("...");

...

foreach ($cats as $cat) {
    $keyboard->addRow(new InlineKeyboardButton([
        'text' => $icon . ' ' . $cat['name'] . ' [' . $count . ']',
        'callback_data' => 'cat_' . $product['id']
    ]));

    /**
     * Back navigate link
     */
    if ($cat === end($cats)) {
        $keyboard->addRow(new InlineKeyboardButton([
            'text' => '馃敊 袧邪蟹邪写',
            'callback_data' => 'category_' . $cat['parent_id']
        ]));
    }
}

And how can I use that in your example?

$items = array_map(function ($cat) {
    return [
        'text'          => $cat['name'],
        'callback_data' => $cat['id'],
    ];
}, $cats);

Just add it to the keyboard after my code above 馃憤

...
$reply_markup = new InlineKeyboard(...$rows);
$reply_markup->addRow(new InlineKeyboardButton([
    'text'          => '馃敊 袧邪蟹邪写',
    'callback_data' => 'category_' . end($cats)['parent_id'],
]));

@noplanmam awww! It's really easy, thank you!

I used foreach after your code 馃槅

Hello again!
Can you help me to create keyboard for both dynamic row and dynamic column? For example turn this array to a simple keyboard

$keys = [
            ['7', '8', '9', '+'],
            ['4', '5', '6', '-'],
            ['1', '2', '3', '*'],
            [' ', '0', ' ', '/']
        ]

I want that to handle responses using this array, I mean use one array for both keyboard and it's responses.

Please check the comments above, you will find your answer there :wink:

Tahnks for your attention, but it's not for dynamic column you fix that with $max_per_row = 2; // or however many you want! .
I mean change it to a keyboard

$keys = [
            ['7'],
            ['4', '5', '6', '-'],
            ['1', '2', '3', '*'],
            [' ', '0']
        ]

How dynamic should it be? If you have an array available, then you obviously already have rows and columns defined.

Can you please elaborate on what you want exactly?

OOPS! Sorry thanks.

        $keys = [
            ['7'],
            ['4', '5', '6', '-'],
            ['1', '2', '3', '*'],
            [' ', '0']
        ];
        $keyboard = new Keyboard(...$keys);

I learn ... from you! And never seen it before in books or tutorials.

Glad you got it sorted! Enjoy.

Hi, I would create buttons dinamic, but i don't now how do, this is my code and my file is in Conversations.php\OnboardingConversation.php

` public function askForDatabase()
{
$question = Question::create('驴Que te gustaria saber ?')
->fallback('Elije una opcion, y espera por la siguiente pregunta')
->callbackId('Vamos !!')
->addButtons([
Button::create('Precio')->value('precio'),
]);

    return $this->ask($question, function (Answer $answer) {
        if ($answer->isInteractiveMessageReply()) {
         } else {
                $this->say(Inspiring::quote());
            }
        }
    });
  }

`

@04211708AC I think you are asking in the wrong project. Are you using this library?

Also, in future it's better to create a new issue instead of commenting on an old closed one :grin:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ttvd94 picture ttvd94  路  4Comments

abbe-cipher picture abbe-cipher  路  4Comments

irmmr picture irmmr  路  3Comments

sineverba picture sineverba  路  3Comments

Bl0ck154 picture Bl0ck154  路  3Comments