From ee5cc29577e1788410fd10b4935bab1b3ea60d34 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Mon, 13 Apr 2026 00:56:38 +0800 Subject: feat: add support for interactive checkbox and radio button input fields --- src/core/browser.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'src/core/browser.cc') diff --git a/src/core/browser.cc b/src/core/browser.cc index e6c63d4..d463b73 100644 --- a/src/core/browser.cc +++ b/src/core/browser.cc @@ -379,6 +379,9 @@ InputAction submit_form( const render::InputField& target_input, std::string body; for ( const auto& in : inputs ) { if ( in.action == target_input.action && !in.name.empty() && in.type != "submit" && in.type != "button" ) { + if ( ( in.type == "checkbox" || in.type == "radio" ) && !in.checked ) { + continue; + } std::string encoded = in.value; for ( char& ch : encoded ) { if ( ch == ' ' ) { @@ -422,6 +425,40 @@ void update_input_value( PageData& page_data, std::size_t index, const std::stri } } +void update_single_line_ui( std::string& line, const std::string& marker, const render::InputField& in ) +{ + const std::size_t pos = line.find( marker ); + if ( pos == std::string::npos ) { + return; + } + const std::size_t end = line.find( ']', pos ); + if ( end == std::string::npos ) { + return; + } + + std::string prefix; + if ( in.type == "checkbox" ) { + prefix = in.checked ? "[X] " : "[ ] "; + } else { + prefix = in.checked ? "(X) " : "( ) "; + } + line.replace( pos, end - pos + 1, marker + prefix + in.value + "]" ); +} + +void update_toggle_ui( PageData& page_data ) +{ + for ( std::size_t i = 0; i < page_data.inputs.size(); ++i ) { + const auto& in = page_data.inputs[i]; + if ( in.type != "checkbox" && in.type != "radio" ) { + continue; + } + const std::string marker = "[I" + std::to_string( i + 1 ) + ":"; + for ( auto& line : page_data.lines ) { + update_single_line_ui( line, marker, in ); + } + } +} + InputAction handle_form_input( const tui::Terminal& terminal, PageData& page_data, const std::string& current_url, @@ -442,11 +479,26 @@ InputAction handle_form_input( const tui::Terminal& terminal, return InputAction::None; } - const auto& target_input = page_data.inputs[index - 1]; + auto& target_input = page_data.inputs[index - 1]; if ( target_input.type == "submit" || target_input.type == "button" ) { return submit_form( target_input, page_data.inputs, current_url, history, history_idx ); } + if ( target_input.type == "checkbox" || target_input.type == "radio" ) { + if ( target_input.type == "radio" ) { + for ( auto& in : page_data.inputs ) { + if ( in.name == target_input.name && in.action == target_input.action ) { + in.checked = false; + } + } + target_input.checked = true; + } else { + target_input.checked = !target_input.checked; + } + update_toggle_ui( page_data ); + return InputAction::None; + } + const std::string query = get_terminal_input( terminal, "Enter Text [I" + std::to_string( index ) + "]:" ); if ( query.empty() ) { return InputAction::None; -- cgit v1.2.3