如何隐藏一行表(或列表项)并在不重新加载页面的情况下更新数据存储

How to hide a row of table (or a list item) and update the datastore without reloading the page?

本文关键字:加载 新加载 情况下 存储 数据 更新 隐藏 何隐藏 一行 列表      更新时间:2023-09-26

我有一个书签列表显示在一个表上。我添加了一个"隐藏"链接来隐藏一个书签,我不想在列表中看到,但我仍然想保持(表和隐藏链接显示只有当你登录)。

现在我通过从数据库中获取项目并将其"display"属性更改为"False"并再次呈现页面来实现。

我认为这可以更好地完成与javascript无需重新加载页面。我发现了几个引用来隐藏表的一行,但不仅仅是隐藏,我还需要将新的显示属性写入数据库。我不明白我怎么能这么做。隐藏行并向数据库写入新的显示属性的最佳方法是什么?谢谢。

这是我现在的代码:

#-----------main table------------#
            display = self.request.get("display")
            main_id = self.request.get("main_id")
            self.response.out.write("""<table class="mytable">
            <tr class="head">
            <th  width="80%">links</th><th>edit tags</th>
            </tr>    
            """)        
            if display == "false":
                k = Main.get_by_id(int(main_id))
                k.display = False
                k.put()
                self.redirect("/useradminpage")
            query = Main.all()
            query.filter("owner", user)
            query.filter("display", True)
            query.order("-date")
            cursor = self.request.get("cursor")
            if cursor: query.with_cursor(cursor)
            e = query.fetch(100)
            cursor = query.cursor()
            for item in e:
                main_id = item.key().id()
                self.response.out.write("""
                    <tr>
                    <td><a href="%s" target="_blank">%s</a><span class=small> (%s) </span><br />
                    <span class=small>%s</span>
                    <a href="/edit?main_id=%s"><span class="small">(edit)</span></a>
                    <a href="/useradminpage?main_id=%s&display=false"><span class="small">(hide)</span></a>
                    <a href="/comment?main_id=%s"><span class="small">(comments)</span></a>
                    <td><a href="/tc?url=%s&main_id=%s&user_tag_list=%s" title="edit tags">%s</a></td>
                    </tr>
                    """ %
                    tuple([item.url,
                    item.title, 
                    urlparse(item.url).netloc,
                    f1.truncate_at_space(item.pitch),
                    main_id,
                    main_id,
                    main_id,
                    item.url,  
                    main_id,  
                    (", ".join(item.tag_list)),
                    (", ".join(item.tag_list)),
                    ]))

            self.response.out.write("""</table>""")    

在RobG的答案中尝试style.display;但是下面的代码不起作用:

...
    for item in e:
        main_id = item.key().id()
        self.response.out.write("""
            <div>
            <tr>
            <td><a href="%s" target="_blank">%s</a><span class=small> (%s) </span><br />
                <span class=small>%s</span>
            <a href="/edit?main_id=%s"><span class="small">(edit)</span></a>
            <a href="/useradminpage?main_id=%s&display=false" onclick="this.parentNode.style.display = "none";><span class="small">(hide)</span></a>
            <a href="/comment?main_id=%s"><span class="small">(comments)</span></a>
            <td><a href="/tc?url=%s&main_id=%s&user_tag_list=%s" title="edit tags">%s</a></td>
            </tr>
            </div>
...

尝试RobG编辑过的答案。在这种情况下,当我单击隐藏按钮时,该行被隐藏了一会儿,然后又被隐藏起来。我不明白为什么。我将包含持有表的代码粘贴到下面:

#-----------holding table start--------#
            self.response.out.write("""
            <table border="0" cellpadding="5" cellspacing="10" >
            <tbody>
            <tr>
            <td>""")
            self.response.out.write("""<td style="vertical-align:top">""")
#-----------tags table start--------#                                   
            self.response.out.write("""<table class="mytable">
            <tbody>
            <tr class="head">
            <th>tags<br />
            <a href="/useradminpage?order=alpha"><span class=small>alpha</span></a><br />
            <a href="/useradminpage?order=date"><span class=small>newest</span></a><br />
            <a href="/useradminpage?order=popular"><span class=small>popular</span></a>
            </th>
            </tr>
            """)      
            if order_by == "popular":
                for tag in most_used:
                    self.response.out.write("""
                    <tr><td><a href="/tag?tag=%s">%s</a></td></tr>
                    """ %
                    (tag, tag))                
            else:
                for tag in unique_tags:                
                    self.response.out.write("""
                    <tr><td><a href="/tag?tag=%s">%s</a></td></tr>
                    """ %
                    (tag, tag))
            self.response.out.write("""</table>""")  
            #holding table first column end
            self.response.out.write("""</td>""")
            #holding table second column start
            self.response.out.write("""<td style="vertical-align:top">""")
#-----------main table------------#
            display = self.request.get("display")
            main_id = self.request.get("main_id")
            self.response.out.write("""<table class="mytable">
            <tr class="head">
            <th  width="80%">links</th><th>edit tags</th>
            </tr>    
            """)        
            query = Main.all()
            query.filter("owner", user)
            #query.filter("display", True)
            query.order("-date")
            cursor = self.request.get("cursor")
            if cursor: query.with_cursor(cursor)
            e = query.fetch(100)
            cursor = query.cursor()
            for item in e:
                main_id = item.key().id()
                self.response.out.write("""
                    <tr>
                      <td><a href="%s" target="_blank">%s</a><span class=small> (%s) </span><br />
                        <span class=small>%s</span>
                        <a href="/edit?main_id=%s"><span class="small">(edit)</span></a>
                        <a href="/useradminpage?main_id=%s&display=false" 
                          onclick="this.parentNode.parentNode.style.display = 'none';">
                        <span class="small">(hide)</span></a>
                        <a href="/comment?main_id=%s"><span class="small">(comments)</span></a>
                      <td><a href="/tc?url=%s&main_id=%s&user_tag_list=%s" title="edit tags">%s</a></td>
                    </tr>
                    """ %
                    tuple([item.url,
                    item.title, 
                    urlparse(item.url).netloc,
                    f1.truncate_at_space(item.pitch),
                    main_id,
                    main_id,
                    main_id,
                    item.url,  
                    main_id,  
                    (", ".join(item.tag_list)),
                    (", ".join(item.tag_list)),
                    ]))
            self.response.out.write("""</tbody></table>""")    
            #holding table end 
            self.response.out.write('<a href="/useradminpage?cursor=%s">More Results</a>' % cursor)
            self.response.out.write("""</td></tr>""")
            self.response.out.write("""</tbody></table>""")
            self.response.out.write("""</div>""")

你已经标记为javascript,但我在页面中没有看到任何脚本。我也没有看到表格或"隐藏"链接。

要隐藏一个元素及其所有子节点,将其style.display属性设置为"none",例如

<div>here is some content
  <button onclick="this.parentNode.style.display = 'none';">Hide</button>
</div>

当然,如果你想再次显示它,那么你需要一个对它的引用,所以你可以这样做:

element.style.display = '';

你可以发送一个HTTP请求到数据库使用各种方法来更新显示值,AJAX(即使用XMLHttpRequest对象)是流行的。

编辑

根据您的回复,您希望在您的页面中有这样的内容(注意处理程序中从双引号到单引号的更改,并且由于您想隐藏整个行,因此需要从链接到TD,然后到TR):

<table>
  <tr>
    <td><a href="..." target="_blank">...</a><span class="small">(...)</span><br>
      <span class=small>%s</span>
      <a href="/edit?main_id=%s"><span class="small">(edit)</span></a>
      <a href="/useradminpage?main_id=%s&display=false"
        onclick="this.parentNode.parentNode.style.display = 'none'; return false;">
      <span class="small">(hide)</span></a>
      <a href="/comment?main_id=%s"><span class="small">(comments)</span></a>
    <td><a href="/tc?url=%s&main_id=%s&user_tag_list=%s" title="edit tags">%s</a></td>
  </tr>
</table>
顺便说一下,TR和TD的结束标记也是可选的,这就是为什么第一个单元格缺少结束标记不会引起任何问题的原因。

编辑2

"全面的"修复是让"隐藏"链接使用一个真正的URL,通过访问服务器来隐藏书签。然后使用DOM ready或onload处理程序为所有的"hide"链接添加一个侦听器

  1. 隐藏元素(如上所示)
  2. 向服务器发送一个更新状态的请求(HTTP请求)
  3. 取消导航(返回false)

无论有没有脚本,你的页面都可以正常工作。

内容如下:

// Helper to get the text inside an element
function getText(el) {
  // If textContent is supported, use it
  if (typeof el.textContent == 'string') {
    return el.textContent;
  }
  // Otherwise if innerText is supported, use it
  if (typeof el.innerText == 'string') {
    return el.innerText;
  }
}
// Function that is attached as a listener
// and does the hiding
var hideRow = (function() {
  // Store an image in a closure, used for HTTP request
  var img = new Image();
  // This is the actual function assigned to hideRow
  return function (e) {
    // Get a reference to the element that called the function
    e = e || window.event;
    var el = e.target || e.srcElement;
    var src;
    // Go up the DOM, get the link href for sending
    // request and then hide the TR
    while (el.parentNode && el.parentNode.tagName) {
      el = el.parentNode;
      // Get the link on the way and store its href value
      if (el.tagName.toLowerCase() == 'a') {
        src = el.href; 
      }
      // When get to the TR, send request and
      // hide the row
      if (el.tagName.toLowerCase() == 'tr') {
        el.style.display = 'none';
        // Send request, using fake image but could use
        // XMLHttpRequest
        img.src = src;
        // Cancel navigation
        return false;
      }
    }
  }
}());
// Adds the above listener to all links that have
// the text "(hide)" in them (case insensitive)
function addListeners() {
  // Get all the links in the document
  var link, links = document.links;
  // A regular expression to match "(hide)"
  var re = /'(hide')/i;
  // For each link...
  for (var i=0, iLen=links.length; i<iLen; i++) {
    // Use a variable for the current link, a bit more efficient
    link = links[i];
    // If the link contains the text "(hide)"
    // add on onclick listener
    if (re.test(getText(link))) {
      link.onclick = hideRow;
    }
  }
}
// Call the add listener function when content is loaded
// Could just add in a script element at the bottomo of 
// the page immediately before the closing body tag
window.onload = function(){
  addListeners();
}

这里没有任何特定于应用引擎的东西-您只需要向您的应用程序发出AJAX请求以设置适当的标志。JQuery是一个非常有价值的库,它可以在客户端简化这类工作。在服务器端,您只需要一个处理程序来获取POST请求中要修改的值,然后对其进行修改并返回状态码。您的客户端代码可以从AJAX调用。