GSMEthesis commited on
Commit
400f2e8
·
verified ·
1 Parent(s): b3e23d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -114
app.py CHANGED
@@ -773,11 +773,8 @@ body, .stApp {
773
  """, unsafe_allow_html=True)
774
 
775
  # ========== توابع اصلی ==========
776
- import streamlit as st
777
- import streamlit.components.v1 as components
778
-
779
  def enhanced_likert_scale(question_data):
780
- """لیکرت اسکیل با HTML/CSS و مدیریت انتخاب با st.session_state"""
781
  question = question_data["question"]
782
  key = question_data["key"]
783
  scale = question_data["scale"]
@@ -791,116 +788,33 @@ def enhanced_likert_scale(question_data):
791
  st.markdown(f"<div style='text-align:right; font-weight:bold; margin-bottom:15px; direction: rtl;'>{question}</div>",
792
  unsafe_allow_html=True)
793
 
794
- # ایجاد خط و نقاط با HTML/CSS
795
- scale_html = f"""
796
- <style>
797
- @font-face {{
798
- font-family: 'B Nazanin';
799
- src: url('https://www.fontyab.com/fonts/b-nazanin/BNazanin.woff2') format('woff2');
800
- }}
801
- .likert-line {{
802
- width: 80%;
803
- height: 2px;
804
- background: #6a0dad;
805
- margin: 0 auto;
806
- position: relative;
807
- display: flex;
808
- justify-content: space-between;
809
- direction: rtl;
810
- }}
811
- .likert-dot {{
812
- width: 18px;
813
- height: 18px;
814
- border-radius: 50%;
815
- background: white;
816
- border: 2px solid #6a0dad;
817
- position: relative;
818
- top: -9px;
819
- cursor: pointer;
820
- transition: background-color 0.2s;
821
- }}
822
- .likert-dot.active {{
823
- background: #6a0dad;
824
- }}
825
- .likert-labels {{
826
- width: 80%;
827
- margin: 5px auto 15px;
828
- display: flex;
829
- justify-content: space-between;
830
- direction: rtl;
831
- font-size: 14px;
832
- font-family: 'B Nazanin', sans-serif;
833
- font-weight: bold;
834
- color: #6a0dad;
835
- }}
836
- .separator-line {{
837
- width: 80%;
838
- height: 2px;
839
- background: #6a0dad;
840
- margin: 20px auto;
841
- }}
842
- @media (max-width: 768px) {{
843
- .likert-line {{
844
- width: 90%;
845
- }}
846
- .likert-labels {{
847
- width: 90%;
848
- }}
849
- }}
850
- @media (min-width: 768px) {{
851
- .likert-container {{
852
- width: 475px;
853
- margin: 0 auto;
854
- }}
855
- }}
856
- </style>
857
-
858
- <div class="likert-container">
859
- <div class="likert-labels">
860
- <span>{labels[0]}</span>
861
- <span>{labels[1]}</span>
862
- </div>
863
- <div class="likert-line">
864
- """
865
-
866
- # اضافه کردن نقاط با جاوااسکریپت برای مدیریت انتخاب
867
- current_value = st.session_state.get(key, 0)
868
- for i in range(1, scale + 1):
869
- value = i
870
- active_class = "active" if current_value == value else ""
871
- scale_html += f"""
872
- <div class='likert-dot {active_class}'
873
- onclick='parent.window.parent.postMessage({{type: "update_selection", key: "{key}", value: {value}}}, "*")'>
874
- </div>
875
- """
876
-
877
- scale_html += """
878
- </div>
879
- </div>
880
- <script>
881
- window.addEventListener('message', function(event) {
882
- if (event.data.type === 'update_selection') {
883
- // به‌روزرسانی st.session_state از طریق Streamlit
884
- parent.window.parent.postMessage({
885
- type: 'streamlit_set_component_value',
886
- value: event.data.value
887
- }, '*');
888
- // به‌روزرسانی ظاهر نقاط
889
- document.querySelectorAll('.likert-dot').forEach(dot => dot.classList.remove('active'));
890
- let dots = document.querySelectorAll('.likert-dot');
891
- dots[event.data.value - 1].classList.add('active');
892
- }
893
- });
894
- </script>
895
- """
896
-
897
- # نمایش کامپوننت HTML و دریافت مقدار انتخاب‌شده
898
- components.html(scale_html, height=60, width=600)
899
 
900
- # به‌روزرسانی st.session_state با مقدار برگشتی
901
- if 'streamlit_component_value' in st.session_state and st.session_state['streamlit_component_value'] is not None:
902
- st.session_state[key] = st.session_state['streamlit_component_value']
903
- del st.session_state['streamlit_component_value']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
 
905
  # نمایش پاسخ انتخاب‌شده
906
  if st.session_state[key] != 0:
@@ -910,7 +824,7 @@ def enhanced_likert_scale(question_data):
910
  st.markdown(f"<p style='text-align:right; color:#6a0dad; direction: rtl;'>پاسخ شما: هنوز انتخاب نشده</p>",
911
  unsafe_allow_html=True)
912
 
913
- # خط جداکننده بنفش
914
  st.markdown("""
915
  <style>
916
  .likert-separator {
@@ -920,10 +834,39 @@ def enhanced_likert_scale(question_data):
920
  margin: 20px auto;
921
  direction: rtl;
922
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
923
  @media (max-width: 768px) {
924
  .likert-separator {
925
  width: 90%;
926
  }
 
 
 
 
 
 
 
 
 
 
 
927
  }
928
  </style>
929
  <div class="likert-separator"></div>
 
773
  """, unsafe_allow_html=True)
774
 
775
  # ========== توابع اصلی ==========
 
 
 
776
  def enhanced_likert_scale(question_data):
777
+ """لیکرت اسکیل با دکمه‌های سفارشی و مدیریت انتخاب با st.session_state"""
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 = [str(i) for i in range(1, scale + 1)]
803
+ selected_value = st.session_state.get(key, 0)
804
+
805
+ for i in range(scale):
806
+ with cols[i + 2]: # شروع از ستون دوم (پس از برچسب‌ها)
807
+ button_key = f"{key}_btn_{i}"
808
+ is_selected = selected_value == int(options[i])
809
+ st.markdown(f'<div style="text-align: center;">', unsafe_allow_html=True)
810
+ if st.button(options[i], key=button_key, disabled=selected_value != 0 and not is_selected):
811
+ st.session_state[key] = int(options[i])
812
+ st.markdown(f'</div>', unsafe_allow_html=True)
813
+
814
+ # نمایش برچسب سمت چپ
815
+ with cols[1]:
816
+ st.markdown(f"<div style='text-align:left; font-size:14px; font-weight:bold; color:#6a0dad; direction: rtl;'>{labels[1]}</div>",
817
+ unsafe_allow_html=True)
818
 
819
  # نمایش پاسخ انتخاب‌شده
820
  if st.session_state[key] != 0:
 
824
  st.markdown(f"<p style='text-align:right; color:#6a0dad; direction: rtl;'>پاسخ شما: هنوز انتخاب نشده</p>",
825
  unsafe_allow_html=True)
826
 
827
+ # خط جداکننده بنفش و استایل‌های سفارشی
828
  st.markdown("""
829
  <style>
830
  .likert-separator {
 
834
  margin: 20px auto;
835
  direction: rtl;
836
  }
837
+ [data-testid="stButton"] {
838
+ margin: 0 5px !important;
839
+ width: 30px !important;
840
+ height: 30px !important;
841
+ border-radius: 50% !important;
842
+ padding: 0 !important;
843
+ text-align: center !important;
844
+ line-height: 30px !important;
845
+ background-color: #fff !important;
846
+ border: 2px solid #6a0dad !important;
847
+ color: #6a0dad !important;
848
+ cursor: pointer !important;
849
+ }
850
+ [data-testid="stButton"]:disabled {
851
+ background-color: #6a0dad !important;
852
+ color: #fff !important;
853
+ }
854
+ /* اجبار به چیدمان افقی در موبایل */
855
  @media (max-width: 768px) {
856
  .likert-separator {
857
  width: 90%;
858
  }
859
+ [data-testid="stHorizontalBlock"] [data-testid="stButton"] {
860
+ margin: 0 2px !important;
861
+ }
862
+ }
863
+ /* تنظیم مرکزیت در فریم موبایل (475px) */
864
+ @media (min-width: 768px) {
865
+ [data-testid="stAppViewContainer"] [data-testid="stHorizontalBlock"] {
866
+ justify-content: center !important;
867
+ width: 475px !important;
868
+ margin: 0 auto !important;
869
+ }
870
  }
871
  </style>
872
  <div class="likert-separator"></div>