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

I have a list of displayed bookmarks in a table . I added a โ€œhideโ€ link to hide a bookmark that I donโ€™t want to see in the list, but I still want to save (the table and the hide link are displayed only if you are logged in).

Now I do this by getting the item from the database and changing its "display" property to "False" and creating the page again.

I think this is best done using javascript without reloading the page. I found some links to hide the table row, but more than hide. I also need to write a new mapping property to the database. I do not understand how I can do this. What is the best way to hide a row and write a new mapping property to the database? Thanks.

This is the code I have now:

#-----------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>""") 

Update

Trying style.display in RobG answer ; but the following code does not work:

 ... 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> ... 

UPDATE

Trying RobG's edited answer . In this case, when I click the hide button, the line is hidden for a moment, and then returns again. I do not understand why. I am pasting below code, including a hold table:

 #-----------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>""") 
0
source share
2 answers

You marked this as javascript, but I do not see any script on the page. I also do not see the table or the "hide" link.

To hide an element and all its child nodes, set its style.display property to "none", for example

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

Of course, if you want to show it again, you will need a link to it so you can:

 element.style.display = ''; 

You can send an HTTP request to the database to update the displayed value using various methods, AJAX (i.e. using the XMLHttpRequest object) is popular.

Edit

Based on your answer, you want your page to have something like this (note the change from dobule to single quotes in the handler, and since you want to hide the entire line, you need to go from link to TD, then to 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> 

By the way, closing tags for TR and TD are also optional, so the missing closing tag for the first cell does not cause any problems.

Edit 2

The โ€œfull-blownโ€ fix is โ€‹โ€‹that the โ€œhideโ€ link uses a real URL that hides the bookmark while making a trip to the server. Then use a ready-made or bootable DOM handler to add a listener to all the "hidden" links that:

  • hides an element (as shown above)
  • sends a request to the server to update the status (HTTP request)
  • cancels navigation (returns false)

This way your page works with or without a script.

Everybody is here:

 // 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(); } 
+2
source

There is no Engine Engine application here - you just need to make an AJAX request for your application to set the appropriate flag. JQuery is a pretty priceless library to simplify this work on the client side. On the server side, you just need a handler that gets the value to change in the POST request, and then changes it and returns a status code. Your client side code can call this from AJAX.

+1
source

All Articles