#88 Dynamic Select Menus

本文介绍如何使用JavaScript实现基于一个下拉菜单选择动态更新另一个下拉菜单的选项。该方法完全在客户端实现,提高了用户界面的响应速度。
See how to dynamically change a select menu based on another select menu using Javascript. In this episode everything is kept client side which leads to a more responsive user interface.
# javascripts_controller.rb
def dynamic_states
@states = State.find(:all)
end

# application_helper.rb
def javascript(*files)
content_for(:head) { javascript_include_tag(*files) }
end

def stylesheet(*files)
content_for(:head) { stylesheet_link_tag(*files) }
end

<!-- people/new.html.erb -->
<% javascript 'dynamic_states' %>
...
<p>
<label for="person_country_id">Country:</label>
<%= f.collection_select :country_id, Country.find(:all), :id, :name, :prompt => "Select a Country" %>
</p>
<p id="state_field">
<label for="person_state_id">State or Province:</label>
<%= f.collection_select :state_id, State.find(:all), :id, :name, :prompt => "Select a State" %>
</p>
// javascripts/dynamic_states.js.erb
var states = new Array();
<% for state in @states -%>
states.push(new Array(<%= state.country_id %>, '<%=h state.name %>', <%= state.id %>));
<% end -%>

function countrySelected() {
country_id = $('person_country_id').getValue();
options = $('person_state_id').options;
options.length = 1;
states.each(function(state) {
if (state[0] == country_id) {
options[options.length] = new Option(state[1], state[2]);
}
});
if (options.length == 1) {
$('state_field').hide();
} else {
$('state_field').show();
}
}

document.observe('dom:loaded', function() {
countrySelected();
$('person_country_id').observe('change', countrySelected);
});
/** @file This library class defines a set of interfaces to customize Ui module Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <Uefi.h> #include <Library/BaseLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/PrintLib.h> #include <Library/BaseMemoryLib.h> #include "FrontPage.h" #include "FrontPageCustomizedUiSupport.h" #include <Library/PrintTestBaseLib.h> #include <Library/HiiLib.h> EFI_GUID FORMSET_GUID = { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }; extern FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate; /* Customize Set Variable */ typedef struct { UINT8 ShowTest; UINT8 FeatureEnabled; } MY_VARSTORE; MY_VARSTORE MyVarStore = {0, 0}; // Initialize with default values // Forward declaration EFI_STATUS UpdateFormVariable ( IN EFI_HII_HANDLE HiiHandle, IN UINT16 QuestionId, IN UINT8 Value ); VOID CreateDynamicControls(IN EFI_HII_HANDLE HiiHandle); /** Customize menus in the page. @param[in] HiiHandle The HII Handle of the form to update. @param[in] StartOpCodeHandle The context used to insert opcode. @param[in] CustomizePageType The page type need to be customized. **/ VOID UiCustomizeFrontPage ( IN EFI_HII_HANDLE HiiHandle, IN VOID *StartOpCodeHandle ) { // // Create "Select Language" menu with Oneof opcode. // UiCreateLanguageMenu (HiiHandle, StartOpCodeHandle); // // Create empty line. // UiCreateEmptyLine (HiiHandle, StartOpCodeHandle); // // Find third party drivers which need to be shown in the front page. // UiListThirdPartyDrivers (HiiHandle, &gEfiIfrFrontPageGuid, NULL, StartOpCodeHandle); // // Create empty line. // UiCreateEmptyLine (HiiHandle, StartOpCodeHandle); // // Create "Continue" menu. // UiCreateContinueMenu (HiiHandle, StartOpCodeHandle); // // Create reset menu. // UiCreateResetMenu (HiiHandle, StartOpCodeHandle); // Create initial dynamic controls based on current variable values CreateDynamicControls(HiiHandle); } /** This function processes the results of changes in configuration. @param HiiHandle Points to the hii handle for this formset. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. **/ EFI_STATUS UiFrontPageCallbackHandler ( IN EFI_HII_HANDLE HiiHandle, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_STATUS Status; // Handle ShowTest checkbox changes (QuestionId = 0x2000) if (QuestionId == 0x2000) { if (Action == EFI_BROWSER_ACTION_CHANGING) { return EFI_SUCCESS; } else if (Action == EFI_BROWSER_ACTION_CHANGED) { // Update value in memory directly, no need to save to NVRAM MyVarStore.ShowTest = Value->u8; Print(L"\nShowTest changed to: %d\n", Value->u8); // Recreate dynamic controls CreateDynamicControls(HiiHandle); Print(L"Dynamic controls recreated\n"); } } // Handle FeatureEnabled checkbox changes (QuestionId = 0x1000) if (QuestionId == 0x1000) { if (Action == EFI_BROWSER_ACTION_CHANGING) { return EFI_SUCCESS; } else if (Action == EFI_BROWSER_ACTION_CHANGED) { // Update value in memory directly, no need to save to NVRAM MyVarStore.FeatureEnabled = Value->u8; Print(L"\nFeatureEnabled changed to: %d\n", Value->u8); // Recreate dynamic controls CreateDynamicControls(HiiHandle); Print(L"Dynamic controls recreated after FeatureEnabled change\n"); return EFI_SUCCESS; } } if (UiSupportLibCallbackHandler (HiiHandle, Action, QuestionId, Type, Value, ActionRequest, &Status)) { return Status; } return EFI_UNSUPPORTED; } /** Update the banner string in the front page. Current layout for the banner string like below: PS: Totally only 5 lines of banner supported. Line 1: Left BannerStr RightBannerStr Line 2: Left BannerStr RightBannerStr Line 3: Left BannerStr RightBannerStr Line 4: Left BannerStr RightBannerStr Line 5: Left BannerStr RightBannerStr <EmptyLine> First menu in front page. ... @param LineIndex The line index of the banner need to check. @param LeftOrRight The left or right banner need to check. @param BannerStr Banner string need to update. Input the current string and user can update it and return the new string. **/ VOID UiCustomizeFrontPageBanner ( IN UINTN LineIndex, IN BOOLEAN LeftOrRight, IN OUT EFI_STRING *BannerStr ) { // Temporarily disable banner update functionality as related PCDs and strings are not defined // If this functionality is needed, the corresponding PCDs and strings should be defined first return; } /** Create dynamic controls based on current variable values in memory **/ VOID CreateDynamicControls(IN EFI_HII_HANDLE HiiHandle) { VOID *StartOp = HiiAllocateOpCodeHandle(); VOID *EndOp = HiiAllocateOpCodeHandle(); if (StartOp == NULL || EndOp == NULL) { Print(L"Failed to allocate opcode handles\n"); return; } // Use variable values directly from memory, no need to read from NVRAM UINT16 VarStoreId = 0; // Use 0 as default VarStore ID Print(L"Using default VarStore ID: %d\n", VarStoreId); Print(L"Creating dynamic controls based on ShowTest=%d, FeatureEnabled=%d\n", MyVarStore.ShowTest, MyVarStore.FeatureEnabled); // Create FeatureEnabled checkbox only if ShowTest != 0 if (MyVarStore.ShowTest != 0) { Print(L"Creating FeatureEnabled checkbox\n"); // Create FeatureEnabled checkbox HiiCreateCheckBoxOpCode( StartOp, 0x1000, // QuestionId VarStoreId, // VarStoreId OFFSET_OF(MY_VARSTORE, FeatureEnabled), // VarStoreOffset 0, // Prompt (will use default) 0, // Help (will use default) EFI_IFR_FLAG_CALLBACK, // Flags 0, // CheckBoxFlags 0 // DefaultId ); // Create PowerOnTime text only if FeatureEnabled != 0 if (MyVarStore.FeatureEnabled != 0) { Print(L"Creating PowerOnTime text\n"); HiiCreateTextOpCode( StartOp, 0, // Text (will use default) 0, // Help (will use default) 0 // Flags ); } } HiiCreateEndOpCode(EndOp); // Insert into form at LABEL_FRONTPAGE_INFORMATION EFI_STATUS Status = HiiUpdateForm( HiiHandle, &FORMSET_GUID, 0x1000, // Form ID StartOp, EndOp ); if (EFI_ERROR(Status)) { Print(L"Failed to update form, Status: 0x%x\n", Status); } else { Print(L"Dynamic controls created successfully\n"); } HiiFreeOpCodeHandle(StartOp); HiiFreeOpCodeHandle(EndOp); } /** Update form variable in memory only (no persistence) **/ EFI_STATUS UpdateFormVariable ( IN EFI_HII_HANDLE HiiHandle, IN UINT16 QuestionId, IN UINT8 Value ) { // Only update the variable structure in memory, do not save to NVRAM if (QuestionId == 0x1000) { MyVarStore.FeatureEnabled = Value; } else if (QuestionId == 0x2000) { MyVarStore.ShowTest = Value; } Print(L"Form variable updated in memory: QuestionId=0x%x, Value=%d\n", QuestionId, Value); return EFI_SUCCESS; }
08-14
基于51单片机,实现对直流电机的调速、测速以及正反转控制。项目包含完整的仿真文件、源程序、原理图和PCB设计文件,适合学习和实践51单片机在电机控制方面的应用。 功能特点 调速控制:通过按键调整PWM占空比,实现电机的速度调节。 测速功能:采用霍尔传感器非接触式测速,实时显示电机转速。 正反转控制:通过按键切换电机的正转和反转状态。 LCD显示:使用LCD1602液晶显示屏,显示当前的转速和PWM占空比。 硬件组成 主控制器:STC89C51/52单片机(与AT89S51/52、AT89C51/52通用)。 测速传感器:霍尔传感器,用于非接触式测速。 显示模块:LCD1602液晶显示屏,显示转速和占空比。 电机驱动:采用双H桥电路,控制电机的正反转和调速。 软件设计 编程语言:C语言。 开发环境:Keil uVision。 仿真工具:Proteus。 使用说明 液晶屏显示: 第一行显示电机转速(单位:转/分)。 第二行显示PWM占空比(0~100%)。 按键功能: 1键:加速键,短按占空比加1,长按连续加。 2键:减速键,短按占空比减1,长按连续减。 3键:反转切换键,按下后电机反转。 4键:正转切换键,按下后电机正转。 5键:开始暂停键,按一下开始,再按一下暂停。 注意事项 磁铁和霍尔元件的距离应保持在2mm左右,过近可能会在电机转动时碰到霍尔元件,过远则可能导致霍尔元件无法检测到磁铁。 资源文件 仿真文件:Proteus仿真文件,用于模拟电机控制系统的运行。 源程序:Keil uVision项目文件,包含完整的C语言源代码。 原理图:电路设计原理图,详细展示了各模块的连接方式。 PCB设计:PCB布局文件,可用于实际电路板的制作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值