【问题标题】:How to "refresh" (re-render) button when text change while using FontAwesome?使用 FontAwesome 时文本更改时如何“刷新”(重新渲染)按钮?
【发布时间】:2018-08-30 17:20:35
【问题描述】:

我有以下用户界面:

从那里我需要动态更改按钮 ArchiveUnarchive 以及来自 FontAwesome 的图标,具体取决于所采取的操作和后端的响应。响应基本上是这样的:

{"row_id":"12518","status":true}

简而言之:

  • 在蓝色行(存档项)中:如果我点击Unarchive 按钮并且响应为true 我应该:删除背景颜色,将按钮文本更改为Archive,将按钮类从@ 更改将 987654331@ 更改为 archive-form 并将 FontAwesome 图标类从 fa fa-arrow-circle-up 更改为 fa fa-arrow-circle-down
  • 在另一行(非归档项目):如果我点击Archive 并且响应为true,那么我应该:添加蓝色背景,将按钮文本更改为Unarchive,将按钮类从archive-formunarchive-form 并将 FontAwesome 图标类从 fa fa-arrow-circle-down 更改为 fa fa-arrow-circle-up

我几乎涵盖了所有内容(我将只显示一个案例的来源,因为它几乎相同,我不想发表大篇幅):

$.ajax({
    url: '/ajax/forms/archive',
    type: 'POST',
    dataType: 'json',
    data: {
        form_id: ids
    }
}).done(function (response) {
    $.each(response, function (index, value) {
        var this_row_tr = $('input[data-form=' + value.row_id + ']').closest('tr'),
            this_btn = this_row_tr.find('.archive-form');

        if (value.status === true) {
            // here I add the background color to the TR 
            this_row_tr.addClass('info');
            // here I swap the button class 
            this_btn.removeClass('archive-form').addClass('unarchive-form');
            // here I swap the button text and also the whole FontAwesome part
            this_btn.text('<i class="fa fa-arrow-circle-up" aria-hidden="true"></i> Unarchive');
        } else if (value.status === false) {
            this_row_tr.addClass('error');
            all_archived = false;
        }
    });

    if (all_archived) {
        toastr["success"]("The forms were archived successfully.", "Information");
    } else {
        toastr["error"]("Something went wrong, the forms could not be archived.", "Error");
    }
}).error(function (response) {
    console.log(response);
    toastr["error"]("Something went wrong, the forms could not be archived.", "Error");
});

但是当我更改 FontAwesome 的文本时问题就来了,因为我得到的是纯文本而不是图标。例如点击第一行的Unarchive会变成这样:

如您所见,除了 FontAwesome 图标外,一切都很好。有什么方法可以刷新按钮以使更改生效?或者您知道其他方法可以实现这一目标吗?

【问题讨论】:

  • 能否请您也添加回复文本?
  • @AlpeshJikadra 完成,在 OP 上
  • HTML 在浏览器中呈现后能否显示?我没有看到用于生成行的脚本与问题相关;除非我遗漏了一些我认为我们需要看到的是:html(您想要修改/操作的)、ajax 脚本和事件处理程序,用于启动和处理对后端的调用和响应文本。
  • @DavidThomas HTML 代码的最后一个 sn-p 是呈现代码的样子。我只是添加了 $.each 循环,但我将编辑 OP 并删除不必要的内容并添加您要问的内容

标签: javascript jquery


【解决方案1】:

您不必像现在这样更改文本,而是使用.html() 并仅替换必要的字符串,这样您就可以保持按钮内容的结构。

试试这个:

// this one is for the Archive action
$.each(response, function (index, value) {
    var this_row_tr = $('input[data-form=' + value.row_id + ']').closest('tr');
    var archiveToUnarchive = this_row_tr.find('.btn[class*="archive"]');
    if (value.status === true) {
        this_row_tr.addClass('info');
        archiveToUnarchive.toggleClass('archive-form unarchive-form')
                .html(archiveToUnarchive.html()
                .replace('Archive', 'Unarchive')
                .replace('fa-arrow-circle-down', 'fa-arrow-circle-up'));
    } else if (value.status === false) {
        this_row_tr.addClass('error');
        all_deleted = false;
    }
});

// this one is for the Unarchive action
$.each(response, function (index, value) {
    var this_row_tr = $('input[data-form=' + value.row_id + ']').closest('tr');
    var unarchiveToArchive = this_row_tr.find('.btn[class*="archive"]');

    if (value.status === true) {
        unarchiveToArchive.toggleClass('archive-form unarchive-form')
                .html(unarchiveToArchive.html()
                .replace('Unarchive', 'Archive')
                .replace('fa-arrow-circle-up', 'fa-arrow-circle-down'));
        this_row_tr.removeClassName('info');
    } else if (value.status === false) {
        this_row_tr.addClass('error');
        all_deleted = false;
    }
});

【讨论】:

  • @ReynierPM,如果我再次单击同一个按钮(如 Archieve 到 UnArchieve,然后再次从 Archieve 到 UnArchieve),这会出现问题。
  • @AlpeshJikadra;因为 OP 有两个 $.each 来分隔场景(unarchiveToArchive 和 archiveToUnarchive),所以应该没有问题。如果 OP 只想使用一个 $.each,那么应该添加更多逻辑来根据按钮的当前状态替换什么,但在这种情况下,相关部分是 OP 所说的卡住事实是他/她使用.text() 而不是.html().replace(),这弄乱了按钮内的结果
  • @AlpeshJikadra。要在没有 ajax 调用的情况下模拟按钮的行为,请尝试:$(document).on('click', 'button.archive-form', function() {$(this).toggleClass('archive-form unarchive-form').html($(this).html().replace('Archive', 'Unarchive').replace('fa-arrow-circle-down', 'fa-arrow-circle-up'));});&lt;button class="btn archive-form" data-form="12518"&gt;&lt;i class="fa fa-arrow-circle-down" aria-hidden="true"&gt;&lt;/i&gt; Archive&lt;/button&gt; HIH
【解决方案2】:

据我了解,您只需要 Archieve 和 UnArchieve 的功能,

你能试试下面的脚本吗

$(document).ready(function(){

    $(".unarchive-form").click(unArchieveToArchieve);
    $(".archive-form").click(archieveUnArchieve);

    function unArchieveToArchieve(){
        var btn = $(this);
        var rowId = $(this).parent().parent().parent().find(".to-upload").attr("data-form");

        var response = [{"row_id":rowId,"status" :true}];

        $.each(response, function (index, value) {
            var this_row_tr = $('input[data-form=' + value.row_id + ']').closest('tr');

            if (value.status === true) {
                this_row_tr.attr('class','');
                $(btn).text("Archieve");
                $(btn).removeClass("unarchive-form");
                $(btn).addClass("archive-form");
                $(btn).click(archieveUnArchieve)
            } else if (value.status === false) {
                this_row_tr.attr('class','error');
                all_deleted = false;
            }
        });
    }
    function archieveUnArchieve(){

        var btn = $(this);
        var rowId = $(this).parent().parent().parent().find(".to-upload").attr("data-form");

        var response = [{"row_id":rowId,"status" :true}];

        $.each(response, function (index, value) {
            var this_row_tr = $('input[data-form=' + value.row_id + ']').closest('tr');

            if (value.status === true) {
                this_row_tr.attr('class','info');
                $(btn).text("Unarchive");
                $(btn).removeClass("archive-form");
                $(btn).addClass("unarchive-form");
                $(btn).click(unArchieveToArchieve)
            } else if (value.status === false) {
                this_row_tr.attr('class' , 'error');
                all_deleted = false;
            }
        });

    }

});

希望这能解决你的问题。

如果您需要更多详细信息,请告诉我。

【讨论】:

    猜你喜欢
    • 2022-07-26
    • 1970-01-01
    • 2017-03-13
    • 2020-04-23
    • 2017-08-22
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多