diff --git a/src/actions/universities/htmx/render_update_score_input.cr b/src/actions/universities/htmx/render_update_score_input.cr new file mode 100644 index 0000000..8151d43 --- /dev/null +++ b/src/actions/universities/htmx/render_update_score_input.cr @@ -0,0 +1,12 @@ +class Universities::Htmx::RenderUpdateScoreInput < HtmxAction + get "/universities/render_update_score_input" do + id = params.get("id") + column_name = params.get("column_name") + column_value = params.get("column_value") + + html UpdateScoreInputPage, + column_name: column_name, + column_value: column_value, + id: id + end +end diff --git a/src/actions/universities/update.cr b/src/actions/universities/update.cr index 8feb134..d45c5bc 100644 --- a/src/actions/universities/update.cr +++ b/src/actions/universities/update.cr @@ -1,10 +1,22 @@ class Universities::Update < BrowserAction put "/universities/:university_id" do university = UniversityQuery.find(university_id) + SaveUniversity.update(university, params) do |operation, updated_university| if operation.saved? - flash.success = "修改成功" - redirect Edit.with(updated_university.id) + if request.headers["HX-Trigger"] == "update_score_input" + param_value = params.nested?(:university).to_a[0] + html( + Htmx::UpdatedScoreInputPage, + id: university.id.to_s, + column_name: param_value[0], + column_value: param_value[1], + action: "/htmx/v1/universities/render_update_score_input" + ) + else + flash.success = "修改成功" + redirect Edit.with(updated_university.id) + end else flash.failure = "出错了" html EditPage, operation: operation, university: updated_university diff --git a/src/components/universities/mouseenter_td.cr b/src/components/universities/mouseenter_td.cr new file mode 100644 index 0000000..bdf6043 --- /dev/null +++ b/src/components/universities/mouseenter_td.cr @@ -0,0 +1,21 @@ +class Universities::MouseenterTD < BaseComponent + needs id : String + needs column_value : String + needs column_name : String + needs action : String + + def render + td( + "hx-trigger": "click", + "hx-swap": "outerHTML", + "hx-get": action, + "hx-vals": "{ +\"column_name\":\"#{column_name}\", +\"id\":\"#{id}\", +\"column_value\": \"#{column_value}\" +}", + ) do + text column_value + end + end +end diff --git a/src/css/app.scss b/src/css/app.scss index 07cc704..16ebfc9 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -25,7 +25,7 @@ body { Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; margin: 0 auto; - max-width: 800px; + max-width: 1920px; padding: 20px 40px; } diff --git a/src/operations/save_university.cr b/src/operations/save_university.cr index 04a1886..19e4dc5 100644 --- a/src/operations/save_university.cr +++ b/src/operations/save_university.cr @@ -12,22 +12,27 @@ class SaveUniversity < University::SaveOperation attribute city_name : String before_save do - validate_required province_code - validate_required province_name - - province = SaveProvince.upsert!( - name: province_name.value.to_s, - code: province_code.value.as(Int32) - ) - - city = SaveCity.upsert!( - name: city_name.value.to_s, - code: city_code.value.as(Int32), - province_id: province.id - ) - - province_id.value = province.id - city_id.value = city.id + # 这两行造成单独 update 某一个字段失败. + # validate_required province_code + # validate_required province_name + + province_name.value.try do |province_name_value| + province_code.value.try do |proinvce_code_value| + province = SaveProvince.upsert!( + name: province_name.value.to_s, + code: province_code.value.as(Int32) + ) + + city = SaveCity.upsert!( + name: city_name.value.to_s, + code: city_code.value.as(Int32), + province_id: province.id + ) + + province_id.value = province.id + city_id.value = city.id + end + end end before_save code_and_batch_level_must_uniq diff --git a/src/pages/universities/htmx/update_score_input_page.cr b/src/pages/universities/htmx/update_score_input_page.cr new file mode 100644 index 0000000..befc9c5 --- /dev/null +++ b/src/pages/universities/htmx/update_score_input_page.cr @@ -0,0 +1,22 @@ +class Universities::Htmx::UpdateScoreInputPage < NoLayout + needs column_name : String + needs column_value : String + needs id : String + + def content + td do + input( + type: "text", + value: "#{column_value}", + name: "university:#{column_name}", + id: "update_score_input", + "hx-put": Universities::Update.with(id).path, + "hx-include": "next input[type='hidden']", + "hx-target": "closest td", + "hx-swap": "outherHTML", + "hx-trigger": "mouseout", + style: "max-width: 60px; max-height: 30px;" + ) + end + end +end diff --git a/src/pages/universities/htmx/updated_score_input_page.cr b/src/pages/universities/htmx/updated_score_input_page.cr new file mode 100644 index 0000000..d690b81 --- /dev/null +++ b/src/pages/universities/htmx/updated_score_input_page.cr @@ -0,0 +1,16 @@ +class Universities::Htmx::UpdatedScoreInputPage < NoLayout + needs column_name : String + needs column_value : String + needs action : String + needs id : String + + def content + mount( + MouseenterTD, + id: id, + column_value: column_value, + column_name: column_name, + action: action + ) + end +end diff --git a/src/pages/universities/index_page.cr b/src/pages/universities/index_page.cr index b22b936..080241c 100644 --- a/src/pages/universities/index_page.cr +++ b/src/pages/universities/index_page.cr @@ -51,6 +51,14 @@ class Universities::IndexPage < MainLayout th "大学名称(点击名称编辑)" th "录取批次" th "补充信息" + th "2023最低分" + th "2023最低位次" + th "2022最低分" + th "2022最低位次" + th "2021最低分" + th "2021最低位次" + th "2020最低分" + th "2020最低位次" th "修改时间" end end @@ -67,9 +75,66 @@ class Universities::IndexPage < MainLayout td do text university.description.to_s end + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.score_2023_min.to_s, + column_name: "score_2023_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.score_2022_min.to_s, + column_name: "score_2022_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.score_2021_min.to_s, + column_name: "score_2021_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.score_2020_min.to_s, + column_name: "score_2020_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.ranking_2023_min.to_s, + column_name: "ranking_2023_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.ranking_2022_min.to_s, + column_name: "ranking_2022_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.ranking_2021_min.to_s, + column_name: "ranking_2021_min", + action: "/htmx/v1/universities/render_update_score_input" + ) + mount( + MouseenterTD, + id: university.id.to_s, + column_value: university.ranking_2020_min.to_s, + column_name: "ranking_2020_min", + action: "/htmx/v1/universities/render_update_score_input" + ) td university.updated_at.to_s("%m月%d日 %H:%M:%S") end end + input(type: "hidden", value: context.session.get("X-CSRF-TOKEN"), name: "_csrf") end end end