GSMEthesis commited on
Commit
a9949ad
·
verified ·
1 Parent(s): 053b4bd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -121
app.py CHANGED
@@ -774,7 +774,7 @@ body, .stApp {
774
 
775
  # ========== توابع اصلی ==========
776
  def enhanced_likert_scale(question_data):
777
- """لیکرت اسکیل با HTML/CSS ساده و مدیریت انتخاب با st.session_state"""
778
  question = question_data["question"]
779
  key = question_data["key"]
780
  scale = question_data["scale"]
@@ -788,121 +788,42 @@ def enhanced_likert_scale(question_data):
788
  st.markdown(f"<div style='text-align:right; font-weight:bold; margin-bottom:15px; direction: rtl;'>{question}</div>",
789
  unsafe_allow_html=True)
790
 
791
- # HTML و CSS برای نمایش خط و نقاط
792
- current_value = st.session_state.get(key, 0)
793
- scale_html = f"""
794
- <style>
795
- @font-face {{
796
- font-family: 'B Nazanin';
797
- src: url('https://www.fontyab.com/fonts/b-nazanin/BNazanin.woff2') format('woff2');
798
- }}
799
- .likert-container {{
800
- max-width: 475px;
801
- margin: 0 auto;
802
- direction: rtl;
803
- text-align: center;
804
- }}
805
- .likert-line {{
806
- display: flex;
807
- justify-content: space-between;
808
- align-items: center;
809
- height: 2px;
810
- background: #6a0dad;
811
- position: relative;
812
- }}
813
- .likert-dot {{
814
- width: 18px;
815
- height: 18px;
816
- border-radius: 50%;
817
- background: white;
818
- border: 2px solid #6a0dad;
819
- cursor: pointer;
820
- position: relative;
821
- top: -9px;
822
- transition: background-color 0.1s;
823
- }}
824
- .likert-dot.active {{
825
- background: #6a0dad;
826
- }}
827
- .likert-labels {{
828
- display: flex;
829
- justify-content: space-between;
830
- font-size: 14px;
831
- font-family: 'B Nazanin', sans-serif;
832
- font-weight: bold;
833
- color: #6a0dad;
834
- margin: 5px 0 15px;
835
- }}
836
- @media (max-width: 768px) {{
837
- .likert-container {{
838
- width: 90%;
839
- }}
840
- .likert-line {{
841
- width: 100%;
842
- }}
843
- .likert-labels {{
844
- width: 100%;
845
- }}
846
- }}
847
- </style>
848
-
849
- <div class="likert-container">
850
- <div class="likert-labels">
851
- <span>{labels[0]}</span>
852
- <span>{labels[1]}</span>
853
- </div>
854
- <div class="likert-line">
855
- """
856
-
857
- # اضافه کردن نقاط
858
- for i in range(1, scale + 1):
859
- value = i
860
- active_class = "active" if current_value == value else ""
861
- scale_html += f"""
862
- <div class='likert-dot {active_class}' id='dot-{key}-{value}'
863
- onclick='this.closest("form").querySelector(`input[value="${{value}}"]').checked = true; this.closest("form").querySelector("button[type=submit]").click();'>
864
- </div>
865
- """
866
 
867
- scale_html += "</div></div>"
868
-
869
- # فرم برای ثبت انتخاب
870
- with st.form(key=f"{key}_form", clear_on_submit=True):
871
- scale_html += f"""
872
- <input type="radio" name="likert_radio" value="1" style="display: none;" {"checked" if current_value == 1 else ""}>
873
- """
874
- for i in range(2, scale + 1):
875
- value = i
876
- scale_html += f"""
877
- <input type="radio" name="likert_radio" value="{value}" style="display: none;" {"checked" if current_value == value else ""}>
878
- """
879
- scale_html += '<button type="submit" style="display: none;">Submit</button>'
880
- components.html(scale_html, height=60)
881
-
882
- selected_option = st.radio(
883
- "",
884
- options=list(range(1, scale + 1)),
885
- index=current_value - 1 if current_value > 0 else None,
886
- label_visibility="collapsed",
887
- key=f"{key}_radio"
888
- )
889
- if st.form_submit_button("ثبت", use_container_width=True):
890
- st.session_state[key] = selected_option
891
-
892
- # جاوااسکریپت برای به‌روزرسانی ظاهر نقاط
893
- st.markdown(
894
- f"""
895
- <script>
896
- document.querySelectorAll('.likert-dot').forEach(dot => {{
897
- dot.addEventListener('click', function() {{
898
- document.querySelectorAll('.likert-dot').forEach(d => d.classList.remove('active'));
899
- this.classList.add('active');
900
- }});
901
- }});
902
- </script>
903
- """,
904
- unsafe_allow_html=True
905
- )
906
 
907
  # نمایش پاسخ انتخاب‌شده
908
  if st.session_state[key] != 0:
@@ -912,7 +833,7 @@ def enhanced_likert_scale(question_data):
912
  st.markdown(f"<p style='text-align:right; color:#6a0dad; direction: rtl;'>پاسخ شما: هنوز انتخاب نشده</p>",
913
  unsafe_allow_html=True)
914
 
915
- # خط جداکننده بنفش
916
  st.markdown("""
917
  <style>
918
  .likert-separator {
@@ -922,17 +843,22 @@ def enhanced_likert_scale(question_data):
922
  margin: 20px auto;
923
  direction: rtl;
924
  }
 
925
  @media (max-width: 768px) {
926
  .likert-separator {
927
  width: 90%;
928
  }
929
  }
930
- /* مخفی کردن دکمه‌های رادیویی پیش‌فرض Streamlit */
931
- [data-testid="stRadio"] > div {
932
- display: none !important;
 
 
 
 
933
  }
934
- /* مخفی کردن دکمه ثبت */
935
- [data-testid="stFormSubmitButton"] {
936
  display: none !important;
937
  }
938
  </style>
 
774
 
775
  # ========== توابع اصلی ==========
776
  def enhanced_likert_scale(question_data):
777
+ """لیکرت اسکیل با دکمه‌های سفارشی و مدیریت انتخاب با st.button"""
778
  question = question_data["question"]
779
  key = question_data["key"]
780
  scale = question_data["scale"]
 
788
  st.markdown(f"<div style='text-align:right; font-weight:bold; margin-bottom:15px; direction: rtl;'>{question}</div>",
789
  unsafe_allow_html=True)
790
 
791
+ # تنظیم چیدمان مرکزی با ستون‌ها
792
+ total_cols = scale + 2 # یک ستون برای هر نقطه + 2 ستون برای برچسب‌ها
793
+ col_widths = [1] * 2 + [2] * scale # 2 ستون برای برچسب‌ها (هر کدام 1) و نقاط (هر کدام 2)
794
+ cols = st.columns(col_widths)
795
+
796
+ # نمایش برچسب سمت راست
797
+ with cols[0]:
798
+ st.markdown(f"<div style='text-align:right; font-size:14px; font-weight:bold; color:#6a0dad; direction: rtl;'>{labels[0]}</div>",
799
+ unsafe_allow_html=True)
800
+
801
+ # نمایش دکمه‌های سفارشی
802
+ options = list(range(1, scale + 1))
803
+ selected_value = st.session_state.get(key, 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
 
805
+ for i, value in enumerate(options):
806
+ with cols[i + 2]: # شروع از ستون دوم (پس از برچسب‌ها)
807
+ button_key = f"{key}_dot_{value}"
808
+ is_selected = selected_value == value
809
+ button_style = "background: #6a0dad; border: 2px solid #6a0dad;" if is_selected else "background: white; border: 2px solid #6a0dad;"
810
+ st.markdown(
811
+ f"""
812
+ <div style='text-align: center;'>
813
+ <button style='width: 18px; height: 18px; border-radius: 50%; {button_style} padding: 0; cursor: pointer; border: none;'
814
+ id='{button_key}' onclick='this.blur();'>
815
+ </button>
816
+ </div>
817
+ """,
818
+ unsafe_allow_html=True
819
+ )
820
+ if st.button("", key=button_key, help=f"Select value {value}", disabled=False):
821
+ st.session_state[key] = value
822
+
823
+ # نمایش برچسب سمت چپ
824
+ with cols[1]:
825
+ st.markdown(f"<div style='text-align:left; font-size:14px; font-weight:bold; color:#6a0dad; direction: rtl;'>{labels[1]}</div>",
826
+ unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
 
828
  # نمایش پاسخ انتخاب‌شده
829
  if st.session_state[key] != 0:
 
833
  st.markdown(f"<p style='text-align:right; color:#6a0dad; direction: rtl;'>پاسخ شما: هنوز انتخاب نشده</p>",
834
  unsafe_allow_html=True)
835
 
836
+ # خط جداکننده بنفش و استایل‌های سفارشی
837
  st.markdown("""
838
  <style>
839
  .likert-separator {
 
843
  margin: 20px auto;
844
  direction: rtl;
845
  }
846
+ /* اجبار به چیدمان افقی در موبایل */
847
  @media (max-width: 768px) {
848
  .likert-separator {
849
  width: 90%;
850
  }
851
  }
852
+ /* تنظیم مرکزیت در فریم موبایل (475px) */
853
+ @media (min-width: 768px) {
854
+ [data-testid="stAppViewContainer"] [data-testid="stHorizontalBlock"] {
855
+ justify-content: center !important;
856
+ width: 475px !important;
857
+ margin: 0 auto !important;
858
+ }
859
  }
860
+ /* مخفی کردن دکمه‌های پیش‌فرض Streamlit برای انتخاب */
861
+ [data-testid="stButton"][help] {
862
  display: none !important;
863
  }
864
  </style>