简体   繁体   English

从 API 数据切换 Div 隐藏/显示

[英]Toggling Div hide/show from API data

Hello all I just want to say thank you in advance.大家好,我只是想提前说声谢谢。 I have a few issues that I would like to address with my shopping cart page.我有几个问题想通过我的购物车页面解决。 This application is made in flask.此应用程序是在烧瓶中进行的。

大车

  1. I have a cart that dynamically populates rows in a table with data from a Restful API created with python.我有一个购物车,它使用 Python 创建的 Restful API 中的数据动态填充表中的行。 At the moment it can also add the prices within the API and display it as the subtotal's html.目前它还可以在 API 中添加价格并将其显示为小计的 html。 I can also hit the delete button next to the item and it deletes that particular element out of the API.我还可以点击项目旁边的删除按钮,它会从 API 中删除该特定元素。 The issue is I need to be able to update the subtotal html upon deleting the item.问题是我需要能够在删除项目后更新小计 html。 Yes I can hit the delete button and upon refreshing the page it will show the correct subtotal but this is unrealistic.是的,我可以点击删除按钮,刷新页面后它会显示正确的小计,但这是不现实的。

  2. Upon adding and deleting items in cart I also have a badge on the shopping cart icon in the upper right hand corner that increments according to how many elements are in API.在购物车中添加和删除项目时,我还在右上角的购物车图标上有一个徽章,该徽章根据 API 中的元素数量增加。 Once I figure out issue with (problem labeled 1) I can figure out how to make the badge decrease upon item deletion.一旦我发现问题(标记为 1 的问题),我就可以弄清楚如何在删除项目时减少徽章。 My main issue here is the cart shows no badge upon moving to different tabs of the website.我的主要问题是购物车在移动到网站的不同标签时没有显示徽章。 The JS is linked to the base html, but I guess since the java script is not running on those particular pages it's not going to show. JS 链接到基本 html,但我猜因为 java 脚本没有在那些特定页面上运行,所以它不会显示。 Not to sure how to work around this.不确定如何解决这个问题。

  3. If there are no items in cart I would like to hide the subtotal html and order button .如果购物车中没有商品,我想隐藏小计 html 和订单按钮 But for some reason I can't get it to toggle and don't know where I should put the code to check if there are no items in API.但是由于某种原因,我无法切换它,也不知道应该将代码放在哪里以检查 API 中是否没有项目。

I'm probably asking too much but if possible please help if you may have any insight.我可能要求太多,但如果可能的话,如果您有任何见解,请提供帮助。 I'll be attaching the code below for javascript, my flask python route, and the html for the cart page.我将附上下面的 javascript 代码、我的 Flask python 路由和购物车页面的 html。

Pricing pricing.html定价定价.html

p{% extends 'base.html' %}
{% block content %}
  <h1>Pricing</h1>
  <div class="row">
    <div class="container col-sm-6">
      <div class="container border">
        <table id='table'>
          <thead>
            <th><h5>Equipment</h5></th>
            <th "><h5>Price</h5></th>
          </thead>
            {% for quip in pricing %}
              <tr style="height:25px;" class="border">
                <td id='pricewidth'>{{quip}}</td>
                <td id='pricewidth' style='text-align:center;'>{{pricing[quip]}}</td>
                <td ><button type="button" name="button" class="btn btn-primary">Add</button></td>
              </tr>
            {% endfor %}
        </table>
      </div>
    </div>
    <div class="container col-sm-6">
      <table id='cart'>
      </table>
      <div id='pricefooter'>
        <h1 style='margin-top:25px; border-top:.5px black solid;'>Subtotal: $<span id='subtotal'>0</span></h1>
        <form action="{{url_for('Order')}}"><button type="submit" name="button" class='btn btn-warning'>Order</button></form>
      </div>
    </div>
  </div>
{% endblock content %}

Cart Javascript pricecart.js购物车 Javascript pricecart.js

var tablerows = document.getElementById('table').rows.length;
var table = document.getElementById('table');
var cart = document.getElementById('cart');
var subtotal = document.getElementById('subtotal');
var username = document.getElementById('username').innerHTML;
var cartBadge = document.getElementById('cartbadge');
var pricesub = document.getElementById('pricefooter');
// On load cart
window.onload = function wowzers(){
  var array = [];
  var sum = 0;
  // Get Data
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'pricing/orders/' + username +'/api', true);
  xhr.onload = function(){
    var data = JSON.parse(this.response);

    cartBadge.innerHTML = data.length

    if(xhr.status >= 200 && xhr.status < 400){
      for(x in data){
        for(key in data[x]){
          array.push(Number(data[x][key]));
          sum+=Number(data[x][key]);
          subtotal.innerHTML = sum;
          row = cart.insertRow(-1);
          // Delete Data
          row.addEventListener('click', function deleterow(){
            index = this.rowIndex;
            // subtotal.innerHTML = sum-Number(cart.rows[index].cells[1].innerHTML);
            $.post('pricing/orders/delete', {
              delete_item: index
            });
             cart.deleteRow(index);
          });
          cell1 = row.insertCell(0);
          cell2 = row.insertCell(1);
          cell3 = row.insertCell(2);
          cell1.innerHTML = key;
          cell2. innerHTML = data[x][key];
          cell3. innerHTML = "<button class='btn btn-danger'>Delete</button>"
        }
      }
      console.log(sum);
    }else{
      console.log(error)
    }
  }
  xhr.send()
}

//Dynamic Cart
for(x = 0; x < tablerows; x++){
  table.rows[x].addEventListener('click', addCartItem);
}
function addCartItem(ev){
  var array = [];
  var sum = 0;
  index = this.rowIndex;
  equipmentCell = table.rows[index].cells[0];
  priceCell = table.rows[index].cells[1];
  equipmentName = equipmentCell.innerHTML;
  equipmentPrice = priceCell.innerHTML;
  // Post Data
  $.post('/pricing/orders/' + username + '/api', {
    javascript_data: JSON.stringify({[equipmentName]:equipmentPrice})
  });
  cartrow = cart.insertRow(-1);

  // Delete Data
  cartrow.addEventListener('click', function deleterow(){
    index = this.rowIndex;
    // subtotal.innerHTML = sum-Number(cart.rows[index].cells[1].innerHTML);
    $.post('pricing/orders/delete', {
      delete_item: index
    });
    cart.deleteRow(index);
  });
  cell1 = cartrow.insertCell(0);
  cell2 = cartrow.insertCell(1);
  cell3 = cartrow.insertCell(2);
  cell1.innerHTML= equipmentName;
  cell2.innerHTML = equipmentPrice;
  cell3.innerHTML = "<button class='btn btn-danger'>Delete</button>";
  // Open Api information
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'pricing/orders/' + username +'/api', true);
  xhr.onload = function(){
    var data = JSON.parse(this.response);
    cartBadge.innerHTML = data.length
    if(xhr.status >= 200 && xhr.status < 400){
      for(x in data){  
        for(y in data[x]){
          array.push(Number(data[x][y]));
          sum+=Number(data[x][y]);
          subtotal.innerHTML = sum;
        }
      }
    }else{
      console.log(error);
    }
  }
  xhr.send();
}

Flask Route routes.py烧瓶路由routes.py

@app.route('/pricing/orders/<user_name>/api', methods=['POST', 'GET'])
@login_required
def api(user_name):
    user_name = current_user.username
    if request.method == 'POST':
        cart.append(json.loads(request.form["javascript_data"]))
    return jsonify(cart)

@app.route('/pricing/orders/delete', methods=['POST', 'GET'])
@login_required
def delete_item():
    if request.method == 'POST':
        print(cart[json.loads(request.form["delete_item"])])
        cart.pop(json.loads(request.form["delete_item"]))
        print(cart)
    return jsonify({"whoa": "there"})

I'm a noob so this may be quite the long winded question an easy problem.我是一个菜鸟,所以这可能是一个冗长的问题,一个简单的问题。 Thanks guys!谢谢你们!

  1. You can try to bind event listener not to every single row (like you do in the loop), but for all of them in one time.您可以尝试将事件侦听器绑定到每一行(就像您在循环中所做的那样),而是一次性绑定到所有行。 After for loop add something like code below and remove event-listener in the loop, hope it will work:在 for 循环之后添加类似下面的代码并删除循环中的事件监听器,希望它会起作用:

     document.querySelectorAll('.row-selector').on('click', function() { ... // do stuff with row })
  2. This problem can be solved using flask's context_processor.这个问题可以使用flask的context_processor来解决。 You can read more about it in official documentation .您可以在官方文档中阅读更多相关信息。 In a word you can put badge length in template's context and then use it anywhere in your templates, for example:总之,您可以将徽章长度放在模板的上下文中,然后在模板的任何地方使用它,例如:

     @app.context_processor def inject_badge_length() badge_length = ... // calculate badge length for current user return {'BADGE_LENGTH': badge_length}

    and then you can use it in template like:然后你可以在模板中使用它,如:

     <div class="badge-length">{{ BADGE_LENGTH }}</div>
  3. Finally, if you have badge length (which can also be 0) you can hide subtotal html using css and javascript, like this:最后,如果您有徽章长度(也可以是 0),您可以使用 css 和 javascript 隐藏小计 html,如下所示:

     #cart { opacity: 0; } #cart.active { opacity: 1; }

    and in js append this to the deleterow event-function (which, by the way, can be anonymous (nameless) function in this case):并在 js 中将此附加到 deleterow 事件函数(顺便说一句,在这种情况下,它可以是匿名(无名)函数):

     if (cartBadge.innerHTML === "0") { cart.classList.remove('active'); }

    and somewhere in the end of 'addCartItem' function append:并在“addCartItem”函数末尾的某处附加:

     if (!cart.classList.contains('active') && cartBadge.innerHTML !== "0") { cart.classList.add('active'); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM