Using clipboard.js with Yii2

1k views Asked by At

I have installed the extension \supplyhog\ClipboardJs\ClipboardJsWidget which seemingly working fine.

but I am struggling to make it work in gridview.

as the code for the extension is already using a widget and gridview itself being a widget, so I think that is making the conflict.

The suggested code outside gridview is like this:

//Button to copy text
<?= \supplyhog\ClipboardJs\ClipboardJsWidget::widget([
    'text' => "Hello World",
    // 'label' => 'Copy to clipboard',
    // 'htmlOptions' => ['class' => 'btn'],
    // 'tag' => 'button',
]) ?>

//Button to copy text from input id
<?= \supplyhog\ClipboardJs\ClipboardJsWidget::widget([
    'inputId' => "#input-url",
    // 'cut' => false, // Cut the text out of the input instead of copy?
    // 'label' => 'Copy to clipboard',
    // 'htmlOptions' => ['class' => 'btn'],
    // 'tag' => 'button',
]) ?>

How I can integrate this in Gridview?

example -

Copy to clipboard

it just shows like this - the third cell being the result of clipboard code.

enter image description here

example of text getting hidden

enter image description here

with the help of @Omer I tried to modified the code like this:

.mycopy{
 position:absolute;
right:-10px;
top:-10px;
}
.mycopy .btn{
padding:2px !important;
}




    [
             'attribute' => 'title',
             'format' => 'raw',
             'value' => function($model){
              $button=\supplyhog\ClipboardJs\ClipboardJsWidget::widget([
                  'text' => $model->title,
                  'label' =>'<i class="far fa-copy" aria-hidden="true"></i>',

            ]);
            return "<div style='position:relative'><div style='margin-right:10px;'>".$model->title."</div><div class='mycopy'>".$button."</div></div>";
        }
    ],

and the result looks like this:

enter image description here

1

There are 1 answers

22
Muhammad Omer Aslam On BEST ANSWER

What i understand is that you are trying to populate the button inside the gridview against every row and when clicked, you want a specific text from that row to be copied in the clipboard.

If that is correct then you can do the following, I will create the example code assuming the user model being used in the GridView and when clicking on the button the Bio of the user will be copied to the clipboard.

<?=
GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        'id',
        'username',
        'active',
        'password',
        'bio',
        [
            'class' => 'yii\grid\ActionColumn',
            'template' => '{view}{update}{delete}{copy}',
            'buttons' => [
                'copy' => function($url, $model, $key){
                    return \supplyhog\ClipboardJs\ClipboardJsWidget::widget([
                            'text' => $model->bio
                    ]);
                },
            ]
        ],
    ],
]);
?>

Note: You can change the $model->description to any column name you are trying to copy 'text' => $model->description.

And if you are planning to show it inside the DataColumn rather than the ActionColumn you can use the following piece of code, it will show the column text and a button under it to copy the text to the clipoard.

[
    'attribute' => 'bio',
    'format' => 'raw',
    'value' => function($model){
        $button=\supplyhog\ClipboardJs\ClipboardJsWidget::widget([
                    'text' => $model->bio,
        ]);
        return $model->bio."<br/>".$button;
    }
],

Update

To replicate the same css as mentioned in your image you should do the following

Add this css on top of your view

$css = <<< CSS
.clip-input-group{
    width:100%;
    float:left;
}
.input-group-button {
    width: 14%;
    vertical-align: middle;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 3px;
    border-top-left-radius: 3px;
    border-bottom-left-radius: 3px;
    float: left;
    border-top-left-radius: 0px;
    border-bottom-left-radius: 0px;
    padding: 5px;
    text-align: center;
    cursor: pointer;
}
.input-group-button i{
    font-size:12px;
}
.clip-input{
   width: 85%;
    display: inline-block;
    float: left;
    border-radius: 3px;
    border-top-right-radius: 3px;
    border-bottom-right-radius: 3px;
    border: 1px solid #ccc;
    border-right-color: rgb(204, 204, 204);
    border-top-right-radius: 0px;
    border-bottom-right-radius: 0px;
    padding: 5px;
    border-right-color: transparent;
}
CSS;
$this->registerCss($css);

Then change your column definition to the following, I am using the fontawesome clipboard icon instead of using the image,

Note: I am not a css expert but managed to create the same, if some one can suggest better classes I am open to suggestions

[
    'attribute' => 'bio',
    'format' => 'raw',
    'value' => function ($model) {
            $button = \supplyhog\ClipboardJs\ClipboardJsWidget::widget([
                'text' => $model->bio,
                'label' => '<i class="fa fa-clipboard" aria-hidden="true"></i>',
                'htmlOptions' => ['class' => ''],
                'tag' => 'a',
            ]);
            $text = $model->bio;
            $html = <<< HTML
            <div class="clip-input-group">
                <input type="text" disabled value="{$text}" class="clip-input">
                <span class="input-group-button">
                    $button
                </span>
            </div>
HTML;

            return $html;
        },
],