مهدی مهدوی
12 ماه پیش توسط مهدی مهدوی مطرح شد
15 پاسخ

دسته بندی آبشاری موبایل

باسلام و احترام خدمت همه دوستان

دوستان حتما به navBar خیلی از سایت ها به خصوص سایت های فروشگاهی توجه کردین.
در سایز موبایل دسته بندی های تو در تو به صورت آبشاری باز و بست میشن و همچنین تو در تو هستن به شکل زیر سایت material ui

material ui

 تصویر
من این کار رو قبلا با jquery انجام میدادم
ولی الآن از React استفاده میکنم و به دنبال یک لایبرری هستم
آیا شما میدونید از چی باید استفاده کنم
یا اصلا چطوری باید این کار رو بکنم بخصوص دسته بندی های تو در تو

@salar.mohammad2013
@ossvahid
@Raymond
@saghari
@mmirabi
@mehdi8686h
@mhyeganeh
@Farzadameri
@error.404
@shahab.roocket


ثبت پرسش جدید
محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
1

سلام و عرض ادب
ببین داداش کلا هرچی تو در تو هست و مشخص نیست تعدادش راحت ترین راه حل تابع بازگشتی هست
من نمیدونم کتابخونه اماده داره یا نه ولی سبک تر از اونه که نیاز باشه براش پکیج نصب کنی
خودت پیادش کن راحت
کلا برای پیاده سازی منو های تو در تو ، درختی ، شاخه ای ، پله ای، اینا خیلی راحت از روش زیر استفاده کن
من این کد رو برای یک نمودار درختی استفاده کردم
مهم کلیتش هست و بعد درکش تغییرات رو خودت بسته به کد خودت بده
و کد شما خیلی کوتاه تر از کد من خواهد بود
در ادامه توضیح میدم.

ببین کد من قراره داده ها رو از یک فایل excel دریافت کنه که تو میتونی خودت یک آرایه براش طراحی کنه که منوت رو کامل توش قرار داده باشی
نوع اطلاعات برای نمودار های تو در تو و درختی به شکلی هست که شما کلا 3 فیلد نیاز داری براش ( id , name , parent_id )
یعنی هر منوی شما یه شناسه داره و اسمی و شناسه ی پدر خودش رو هم نگه میداره که کیه پدرش
اون منو های اصلی که پدر ندارن و سطر لایه اول شما هستن رو هم قرار داد کن 0 بزار مقدار توش رو
 تصویر
توی مثال بالا به جای id از کد استفاده شده و به جای 0 هم از null استفاده کردم توی اکسل خودم
ویویی که رسم شده به شکل زیر هست و کد من یک ریشه ی اصلی داره ولی فرقی نمیکنه در کل راه حل رو فقط کافیه درک کنی
 تصویر
کد به این صورته


        var excelRows;
        function ProcessExcel(data) {
            //Read the Excel File data.
            var workbook = XLSX.read(data, {
                type: 'binary'
            });
            //Fetch the name of First Sheet.
            var firstSheet = workbook.SheetNames[0];
            //Read all rows from First Sheet into an JSON array.
            excelRows = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[firstSheet]);
            var rootIndex = excelRows.findIndex(cell => cell.parent_code === 'null')
            var root = excelRows.find(cell => cell.parent_code === 'null')
            var tree = buildTreeNodes(root)
            $('.tree').html(tree)
            var dvExcel = $("#dvExcel");
            dvExcel.html("");
        };

        function buildTreeNodes(node) {
            var childs = excelRows.filter(cell => cell.parent_code === node.code)
            var result = `<li>
                            <div>${node.name}</div>`
                        ;
            if(childs){
                result+='<ul>';
                for (const childNode of childs) {
                    result+= buildTreeNodes(childNode)
                }
                result+='</ul>';
            }
            result +='</li>'
            return result;
        }

بخش هاییش که برای خوندن و دریافت فایل اکسله که مشخصه و مهم هم نیست
یه بخش پیدا کردم نود پدر دارم که null رو پیدا کردم ( البته برای من به صورت رشته نوشته شده توی اکسل برای همینم رشته سرچش کردم واقعا نال نبوده ) بعد پیدا کردنش تابع ساخت node ها و فرزند های اون رو صدا زدم
شما باید توی همین مرحله خود نود های پدر رو هم حلقه کنی و به اضای هر کدوم تابع فرزند هاش رو صدا بزنی همین
جون نود های پدر که با یه سرج ساده توی ارایه و اون های که شناسه پدرشون رو صفر گذاشتی به دست میان
توی تابع buildTreeNode هم ویو مربوطه رو باید قرار بدی مثل من
اسم نود پدر رو توی یک li و فرزند هاش رو توی ul قرار دادم همین
فرزند که توی ul رفته خودش یک منو یا node هست دیگه
دوباره به صورت بازگشتی تابع فراخوانی میشه تا زمانی که همه ی فرزنداش رسم بشه

var childs = excelRows.filter(cell => cell.parent_code === node.code)

این کد هم که میدونی دیگ چیکار میکنه
توی اون ارایه منو هات یا فایل اکسل من دنبال فرزند های منو میگرده ، چطوری ؟ هر منویی که شناسه ی پدرش با شناسه ی این منو برابر باشه یعنی فرزند همین منو یا node مربوطه هست

اگر دقت کنی کل کد 10 خط هم نمیشه واقعا بقیش مازاد فایل اکسلو داده های اونه که دریافتش کرده
کد خیلی سبک و راحتیه نیاز به پکیج نداری


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

ولی اینم در پایان اضاف کنم که منوی شما درسته ابشاری هست
ولی معمولا توی سایت وگوشی برای منو 2 یا سه سطح بیشتر در نظر نمیگیرن و پیاده نمیکنن
پس با فرض این که منوت رو میدونی چند سطح داره خودت راحت میتونی برای 3 سطح ظاهرشو پیاده کنی بدون تابع بازگشتی و این داستانا
من فرم کلی کد رو برای n فرزند و سطح برات قرار دادم ولی معمولا برای منو بعیده که تعداد سطح ثابت نباشه و تو در توی چندین سطح نامعلوم داشته باشیمش


مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش آپدیت شد
0

باسلام و احترام
@salar.mohammad2013
مشکل من روش پیاده سازی داده ها نیست
من به دنبال UI هستم
اینکه یک تابع در jquery بوده به نام slideToggle که باعث میشد بعد از کلیک کردن روی یک المنت المنت دیگر به صورت آبشاری باز و بست بشه همونظور که در تصویر دیدید
من به دنبال پیاده سازی UI به صورت زیر هستم
برای همین میگم آیا کتابخانه براش هست یا نه
میخوام یک کتابخانه باشه که فرضا بگه اگر روی فلان آی دی کلیک شد حالا فلان المنت slideToggle بشه
تمام بحث من یاده سازی UI هست نه چگونگی دریافت دیتا های دسته بندی و نمایش آنها
امیداوارم متوجه منظورم شده باشید
این حالت toggle و animation تقریبا در خیلی از سایت ها در nav bar خیلی از سایت های معروف داکیومنتی هست
 تصویر


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

بله عذر میخوام متوجه منظورتون نبودم
سایت رو نگاه کردم خیلی کار خاصی نمیکنه مود موبایل و کامپیوتر هم فرقی نداشت عملا منوش هردو به یه شکل اضاف میشد زیر دسته ها
 تصویر

این اصلا چیز سختی نیست که بخوایی براش پکیج نصب کنی
عملا این چیزا پکیج نداره چون به ظاهری که میسازی ربط داره نه کاری که میکنه
فقط کافیه توی ری اکت یه state داشته باشی که لیست منو هات و باز بودن و نبودنش رو نگه داشته باشی is_open
توی ویو براشون transition قرار میدی و height در حالت اولیه 0 بزار بعد از این که open شد height رو مثلا auto کن (از طریق حذف و اضاف کردن کلاس مورد نظر با چک کردن state)
خودش ابشاری دراز میشه و نمایش میده خودشو توی ui
فکر نکن که دونه دونه داره زیر دسته ها اضاف میشه و این ابشاری شده
کلا داره با height بازی میکنه همین
کدش رو یه نگاه ساده بزنی همه جاش transition

.css-c4sutr {
    height: auto;
    overflow: visible;
    -webkit-transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
    transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}

مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش آپدیت شد
0

@salar.mohammad2013
ظاهرا این پکیج خودشه چون تعداد نصب زیادی هم داشته
rc-menu


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش آپدیت شد
0

دو سه باره دارم میام وقت بزارم نمیشه واقعا چون زمانبر هست
چون پایه ریزی میخواد که همون ظاهر بیسش رو پیدا کنم بزارم داده بدم همشون و بعد بیام تازه سره بازو بسته شدنش وقت بزارم تست کنم
میدونم چی میگی این auto کار نکردنش رو خودمم داشتم چالشش رو
لطفا اگر میتونی خودت پیادش کن حداقل ویو کامل و ساده
فایلشو بده نمودار درختی باز شدشو
که ما سر بازو بسته شدنش بیاییم تلاش کنیم
چون از یک طرف از وقتی توی react اومدم کلا هم از tailwind دارم استفادخ میکنم و باز همین فرمت css خالی زدن و لینک دادنش توی ری اکت و کلاس گزاری و تکمیل یک قالب وقت گیر هم هست
لطفا تکمیل بکن ظاهر رو و فقط همون مشکل رو بیار ک روش تلاش کنیم و پیادش کنیم

سایتی هم که فرستادی اره دیدم بخش inline چیزی که میخوایی هست باید دانلود کنی و ببینی کدش چیه
اگرم حس میکنی نیازت برطرف میکنه خب ازش استفاده کن


مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش مطرح شد
0

سلام خوبی
@salar.mohammad2013

من یه کدی زدم همش js هست و شامل فایل App.jsx در react و یک فایل کوچیک Style.css
کد هارو قرار میدم لطفا تو سیستمت پیاده سازیشون کن
برای من به درستی کار میکنه
به شکلی هست که استفاده ازش ساده هست کامنت های بالاش رو بخونی متوجه میشی
حتی میشه به عنوان کتابخونه ازش استفاده کرد چون حالت Nested Lists هست
و اینکه bootstrap-icon رو هم باید نصب کنی برای آیکن arrow
تشکر

css


.child-list {
  max-height: 0px;
  overflow: hidden;
  transition: 0.2s;

}

.is-open-toggle {
  max-height: 1000px;
  transition: 0.5s;
}

li {
  padding: 5px 0;
}

App.jsx

/*
 * All lists are placed inside <ul className="list-menu">...</ul>

 * If your list has No-Children ---insert--->  
  <li className="parent-list">...name-list...</li> 

 * But for Nested Lists ---insert---> 
  <li className="parent-list">
    <span className="target-click">Electronic</span>
    <span className="insert-icon">...mustEmpty...</span>
    <ul className="child-list">
    <li className="parent-list">nameItem</li>
    <li className="parent-list">nameItem</li>
    <li className="parent-list">nameItem</li>
    </ul>
  </li>
*/

import { useEffect } from "react";
import "./style.css";

const App = () => {
  useEffect(() => {

    const childLists = document.querySelectorAll("ul.list-menu li.parent-list ul.child-list");

    childLists.forEach((childList) => {

      // Start insert-icon into <span class="insert-icon">
      const childListParentElement = childList.parentElement; // li's has child's
      const iconInsertInto = childListParentElement.querySelector("span.insert-icon"); // path for [insert] tag icon
      const caretIcon = '<i class="bi bi-caret-right-fill"></i>'; // tag icon
      iconInsertInto.innerHTML += caretIcon; // insert tag icon to path
      // End insert-icon <span class="insert-icon">

      // target-click Start
      const targetClick = childListParentElement.querySelector("span.target-click"); // for click
      const iconTarget = childListParentElement.querySelector("span.insert-icon i"); // for toggle -> arrow
      targetClick.style.cursor = "pointer"; 

      targetClick.addEventListener("click", (e) => {
        const boxHeightToggleTarget = childListParentElement.querySelector("ul.child-list"); // select ul for toggle-height
        boxHeightToggleTarget.classList.toggle("is-open-toggle"); // toggle-height

        // toggle arrow-icon
        const isCloseArrow = iconTarget.classList.contains("bi-caret-right-fill"); // If arrow was closed

        // If arrow was closed
        if (isCloseArrow) { 
          iconTarget.classList.remove("bi-caret-right-fill");
          iconTarget.classList.add("bi-caret-up-fill");
        } else {
          iconTarget.classList.add("bi-caret-right-fill");
          iconTarget.classList.remove("bi-caret-up-fill");
        }
        // target-click End
      });
    });
  }, []);

  return (
    <>
      <ul className="list-menu">

        <li className="parent-list">

          <span className="target-click">Electronic</span>
          <span className="insert-icon"></span>

          <ul className="child-list">
            <li className="parent-list">
              <span className="target-click">LapTop</span>
              <span className="insert-icon"></span>

              <ul className="child-list">
                <li className="parent-list">Asus</li>
                <li className="parent-list">MacBook</li>
                <li className="parent-list">hp</li>
              </ul>
            </li>

            <li className="parent-list">
              <span className="target-click">USB</span>
              <span className="insert-icon"></span>

              <ul className="child-list">
                <li className="parent-list">256 GB</li>
                <li className="parent-list">128 GB</li>
                <li className="parent-list">64 GB</li>
              </ul>
            </li>
          </ul>
        </li>

        <li className="parent-list">
          <span className="target-click">Mobile</span>
          <span className="insert-icon"></span>

          <ul className="child-list">
            <li className="parent-list">
              <span className="target-click">Samsung</span>
              <span className="insert-icon"></span>

              <ul className="child-list">
                <li className="parent-list">Tablets</li>

                <li className="parent-list">
                  <span className="target-click">Galaxy</span>
                  <span className="insert-icon"></span>

                  <ul className="child-list">
                    <li className="parent-list">A54 5G</li>
                    <li className="parent-list">A24</li>
                    <li className="parent-list">A 34</li>
                  </ul>
                </li>
              </ul>
            </li>

            <li className="parent-list">iphon</li>
          </ul>
        </li>

      </ul>
    </>
  );
};

export default App;

محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

سلام عزیز قربونت

برای من به درستی کار میکنه

متوجه نشدم
الان درست شد کار میکنه مشکل حله ؟
چیو تست کنم توی سیستمم ؟


مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش مطرح شد
0

@salar.mohammad2013
کد هارو که دادم وارد کردی ؟
منظورم از اینکه ببین به درستی کار میکنه این بود که کد هارو واردشون کنی و نظرت رو بگی


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

نه وارد نکردم چون گفتید کار میکنه خواستم بدونم مشکل چی هست که بدونم اصلا دنبال چی باید باشم.
چشم اخر وقت حتما نصب میکنم تست میکنم ببینم چطوری شده عزیز


مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش مطرح شد
0

@salar.mohammad2013
اوکیه کار میکنه
خواستم ببینی در حدی هست که کاربرها بخوان ازش استفاده کنن
چون حالت لایبرری به خودش گرفته و کار رو ساده کرده


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

حله داداش مرسی که ارسال کردی حتما نگاه میکنمش
خوبه که بقیه دوستان هم سرچ کنن ببین پاسخ رو
میتونی پاسخ خودت رو پاسخ برتر کنی که استفاده کنن دوستان


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

فقط برو که بلاکی 😁😀
nextjs نصب کردم و کدت کپی کردم حلا هی میزنم کار نمیکنه
کل کدتو نکاه کردم میبینم مشکل از toggle کردنه
add میزارم بجاش میبینم اوکیه
بعد کلی تلاش فهمیدم مشکل از strict mode هست که هر تابع رو دو بار سریع اجرا میکنه
یه بار باز میشده و دفه دوم چون تاگل بوده کلاس حذف میشده اینگار ن انگار که داره کار میکنه
خلاصه که ایکونا بوت استرپم نیست انگار برام فک کنم بعد نصب ایمپورت خاصی هم داشت که مهم نیست
کلیت همون باز شدن لیست بود که خوب بود اقا چیزی بود ک نیاز داشتیدش😅😅😅😅😅

 تصویر


مهدی مهدوی
تخصص : FrontEnd
@mehdimctb 12 ماه پیش مطرح شد
0

@salar.mohammad2013
سلام خوبی من فکر میکنم یه اشتباهی شده
چون نمیشه برای من به درستی کار کنه و برای شما نه
شما در. react نه. nuxtjs در کامپوننت App فقط کد رو کپی کنید
و در همون، مسیر فایل. style. css دوباره چک کنید
صفحه رو رفرش کنید
چون خیلی بعیده که کار نکنه
لطفا خبرش رو بده


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 12 ماه پیش مطرح شد
0

عزیز کار میکنه کد
فقط ایکون های بوت استرپش نیست
next فریم وورک ری اکت هست
مشکل چیز دیگری بود که توضیح دادم حل شد
style css هم که گزاشتی داره کار میکنه میبینی که مارجین و پدینگ درسته
شما اسکرین بده از چیزی که داری فقط icon هاشو ببینم
برای من ایکون هاش نیست همین
پروژه که سالمه


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام