Oracle APEX 23:实现带数量选择器的菜品列表GUI技术问询
Oracle APEX 23 餐厅自助点餐GUI实现方案
针对你遇到的Cards组件无法嵌入数量选择器的问题,给你两个可行的实现方案,同时搞定菜品展示、数量选择、Collection存储和总价实时更新:
一、优先方案:用Interactive Grid的卡片模式
原生Cards组件确实不支持直接加数量选择器,直接用Interactive Grid(IG)的卡片布局就行,它能满足所有需求:
- 新建基于菜单表的IG,把布局改成「卡片」模式
- 加个数值型列(命名
QUANTITY),类型选「数值字段」,设最小值0、默认值0,这就是数量选择器 - 配置图片列:把
ITEM_IMAGE(BLOB)列设为「图像」类型,指定对应MIME类型,确保图片正常显示 - 自定义卡片模板:在IG的「卡片模板」设置里,调整HTML结构,把菜品名称、价格、图片、数量框摆到合适位置
二、把选品和数量存入Collection
用动态Action实现数量变化时同步更新Collection:
- 建一个服务器端动态Action,触发条件设为「IG的QUANTITY列值变化」
- 在「执行服务器端代码」步骤里写PL/SQL:
DECLARE l_item_id NUMBER; l_quantity NUMBER; l_item_name VARCHAR2(255); l_item_price NUMBER; BEGIN -- 取当前行的菜品信息和数量(替换成你实际的页面项/列名) l_item_id := :PXX_ITEM_ID; l_quantity := :PXX_QUANTITY; l_item_name := :PXX_ITEM_NAME; l_item_price := :PXX_ITEM_PRICE; -- 先删掉集合里该菜品的旧记录 DELETE FROM apex_collections WHERE collection_name = 'CART_ITEMS' AND attr_number01 = l_item_id; -- 数量大于0就加新记录到集合 IF l_quantity > 0 THEN apex_collection.add_member( p_collection_name => 'CART_ITEMS', p_attr_number01 => l_item_id, -- 菜品ID p_attr_char01 => l_item_name, -- 菜品名 p_attr_number02 => l_item_price, -- 单价 p_attr_number03 => l_quantity -- 数量 ); END IF; END; - 页面加载时初始化集合:在页面「加载前」流程加PL/SQL,确保
CART_ITEMS集合存在:IF NOT apex_collection.collection_exists('CART_ITEMS') THEN apex_collection.create_collection('CART_ITEMS'); END IF;
三、实时更新总价
- 建个只读页面项(比如
PXX_TOTAL_PRICE)用来显示总价 - 建动态Action,触发条件设为「IG数量列变化」或「Collection更新」,执行两步:
- 执行服务器端代码算总价:
SELECT NVL(SUM(attr_number02 * attr_number03), 0) INTO :PXX_TOTAL_PRICE FROM apex_collections WHERE collection_name = 'CART_ITEMS'; - 刷新
PXX_TOTAL_PRICE页面项,让前端实时显示最新总价
- 执行服务器端代码算总价:
四、备选方案:自定义动态内容卡片
如果IG卡片模式不符合你的UI需求,就用动态内容区域自己拼卡片:
- 建动态内容区域,用PL/SQL生成带数量框的卡片HTML:
DECLARE CURSOR c_menu IS SELECT item_id, item_name, item_price, item_image FROM menu_table; BEGIN FOR rec IN c_menu LOOP HTP.P('<div class="custom-card" style="border:1px solid #eee; padding:1rem; margin:1rem; width:200px;">'); -- 显示菜品图片 HTP.P('<img src="' || apex_util.get_blob_file_src('PXX_IMAGE', rec.item_id) || '" alt="' || rec.item_name || '" style="width:100%; height:120px; object-fit:cover;">'); -- 菜品信息 HTP.P('<h4 style="margin:0.5rem 0;">' || rec.item_name || '</h4>'); HTP.P('<p style="margin:0.5rem 0;">价格: $' || rec.item_price || '</p>'); -- 数量选择器(APEX数值项) HTP.P(apex_item.text( p_idx => 1, p_value => 0, p_attributes => 'class="quantity-input" data-item-id="' || rec.item_id || '" data-price="' || rec.item_price || '" style="width:60px;"' )); HTP.P('</div>'); END LOOP; END; - 加JavaScript监听数量变化,通过AJAX更新Collection和总价:
$(document).on('change', '.quantity-input', function() { const itemId = $(this).data('item-id'); const price = $(this).data('price'); const quantity = parseInt($(this).val()) || 0; // 调用AJAX进程更新购物车集合 apex.server.process('UPDATE_CART', { x01: itemId, x02: price, x03: quantity }, { success: () => { // 计算并更新总价 apex.server.process('CALCULATE_TOTAL', {}, { success: (total) => { apex.item('PXX_TOTAL_PRICE').setValue(total); } }); } }); }); - 建两个AJAX进程:
UPDATE_CART负责处理Collection的增删,CALCULATE_TOTAL负责计算总价并返回结果
内容的提问来源于stack exchange,提问作者Vihen Theekshadha
相关产品推荐
相关产品推荐

