R,Shiny,DT表,替换数据

时间:2018-01-23 18:12:35

标签: r shiny dplyr dt

我正在尝试通过文本输入和操作按钮编辑表格。另外,我希望数据保持不变,这样如果我重新加载应用程序或在文本输入中输入新数据,则先前的输入不会恢复到之前的值。

我觉得可能有一种简单的方法可以做到这一点,我看到这样的事情,我们可以删除行:Are table displayed on shiny,read only?但是这对你重新加载应用程序没有帮助。此外,我似乎无法将其应用于更换特定单元格。

下面我有一些使用mtcars的简化代码。我添加了两列,一列给出了车号,另一列表示如果车好的话。基本上,我希望能够输入1,然后行Car_number 1将Good_car列更改为True。然后,当我输入2时,我希望前一个和现在两个都是真的。最后,下次我重新加载应用程序时,我希望它们仍然是真的。

第二个数据表只显示我知道dplyr mutate replace可以更改数据表中的特定内容,因为当我输入车号时,它会将Good_car更改为T,直到输入发生变化它会回复。

$(document).ready(function() {

    // Document is ready.

    var data = {};

    console.log('log');

    $('.tile').bind('click', addOrder);

});

$(document).on('change', '.quantity', function() {

    console.log('quantity change event');

    // Input Total calc

});

function addOrder() {

    var anchor_id = $(this).children('div').find('.id > input').val();
    var anchor_name = $(this).children('div').find('.name').html();
    var anchor_price = $(this).children('div').find('.price').html();
    var anchor_number = $(this).children('div').find('.number').html();

    var data = {
        'product_id':  anchor_id,
        'product_name': anchor_name,
        'product_price': anchor_price,
        'product_quantity': anchor_number
    };

    var rows = $('#orders tr');

    var check = checkTableItems(data);

    if( !check ) {

        populateTable(data);

    } else {

        console.log('value increased!');

    }

}

function checkTableItems(data) {

    var b = false;
    var rows_count = $('#orders tr').length;

    console.log('row count: ' +rows_count);
    console.log('selected item id: ' +data.product_id);

    if ( rows_count == 0 ) {

        b = false;
        console.log('first item');

    } else {

        console.log('checkingTable');

        for( var i = 0; i <= rows_count; i++ ) {

            console.log('number of row ' + i);

            row_value = $('#orders > tr > td > input')[i];

            if( row_value == undefined ) {
                continue;
            }

            if( row_value.value == data.product_id ) {

                console.log('found item, increasing value');
                $('input[name="demo1"]')[i].value = +$('input[name="demo1"]')[i].value + 1;
                b = true;
            }

            if(b) {

                return true;
                break;

            }

        }

    }

    if(!b) {
        console.log('New item in table');
        return false;
    }

}



function populateTable(data) {

    var value = '<input value="'+data.product_id+'" />';

    var order_id = '<td style="display:none" class="productID">'+value+'</td>';
    var order_close = '<td><button href="#" class="btn default red-stripe"><i class="fa fa-close"></i></button></td>';
    var order_name = '<td class="productname">'+data.product_name+'</td>';
    var order_price = '<td>'+data.product_price+'</td>';
    var order_quantity = '<td class="hidden-xs" ><div class="form-group"><div class="input-inline input-small"><input type="text" value="1" name="demo1" class="quantity form-control touchspin_demo1" ></div></div></td>';

    $('#orders').append('<tr>'+order_id+order_close+order_name+order_quantity+order_price+'<td class="total">1</td></tr>');

    ComponentsFormTools.init(); 

    return false;
}

我也怀疑Replacedata会这样做,但不可否认的是,文档有时仍然可以超越我的头脑:https://rdrr.io/cran/DT/man/replaceData.html

1 个答案:

答案 0 :(得分:1)

您非常接近,您需要做的就是修改observeEvent

observeEvent(input$action, {mtfinal(mtfinal()%>%
     mutate(Good_car = replace(Good_car, Car_number == input$text, T)))})

为什么您的解决方案无法按照您的意愿执行操作:您调用mtfinal()的值并从那里进行过滤。但是,您不会将结果表写回mtfinal()。因此,下次要更新时,请再次使用mtfinal()的初始值。由于您可以通过执行reactiveValy x设置y(x)的新值,我们需要做的就是将整个语句包装在mtfinal(...)中。希望这有帮助!