0

I want to add specific event messages given from "calendar_msgs" under specific months. For example, under January, I want to put the specific info that calendar_msgs has for the month January which is "Сайхан амарна" with a nested style and the same approach should go for all the other months. I tried to make a nested list but there seems to be a problem.

var monthNames = ["January ", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var daysOfTheWeek = ["S", "M", "T", "W", "T", "F", "S"]

var d = new Date();
var year = d.getFullYear();

var curMonth = d.getMonth();
var today = d.getDate();

var calendar_msgs = {
  jan: {
    1: "Сайхан амарна"
  }, // Event info for January that has to be under January etc.
  feb: {
    1: "Сагсны тэмцээнтэй",
    3: "Шагнал гардуулна даа",
    17: "Жавхлан багшийн лаб 2-ыг хийнэ"
  },
  mar: {
    2: "Энэ лабынхаа хугацааг сунгах уу яах вэ гэдэгээ шийднэ",
    6: "Энд юу бичье дээ байз",
    8: "Эмэгтэйчүүддээ баяр хүргэнэ дээ"
  },
  apr: {
    1: "Бүгдээрээ худлаа ярьцаагаагаарай"
  },
  may: {
    10: "Энэ сард ч ёстой юу ч болдоггүй сар даа"
  },
  jun: {
    6: "Жавхлан багшийн төрсөн өдөр"
  },
  jul: {
    4: "Хичээл амарсаан ураа"
  },
  aug: {
    1: "Хөдөө явдаг цаг даа",
    25: "Хичээл сонголт эхэллээ"
  },
  sep: {
    1: "9-н сарын нэгэн боллоо ерөөсөө бидний баяр даа"
  },
  oct: {
    13: "Сур сур бас дахин сур"
  },
  nov: {
    2: "Сурсаар л бай"
  },
  dec: {
    20: "Өвлийн семистер хаагдах нь дээ",
    30: "Дүн гаргаж дууслаа баярлалаа баяртай"
  }
}

function eventList() {

  var ul = document.createElement('ul');
  var list = document.getElementById("events");
  list.appendChild(ul);
  var listItem;
  var listItem2;
  var breakItem;
  for (i = 0; i < 12; ++i) {
    listItem = document.createElement('li');
    breakItem = document.createElement('br');

    if (monthNames[i] == 1) {
      listItem.innerHTML = calendar_msgs.jan[1];
      ul.appendChild(listItem);
      ul.appendChild(breakItem);
    }
    listItem.innerHTML = monthNames[i];
    ul.appendChild(listItem);
    ul.appendChild(breakItem);
  }
}

eventList();
<h1 id="year">2021 Calendar</h1>
<div class="calendar">
</div>
<div id="events">
  <h2 id="eventText">Events</h2>
</div>

3 Answers 3

2

I merged data into one object and used some cool es6 features check it out :)

ES6 constants For-of operator

and transforming from objects into arrays Object.entries Object.values

const calendar_data = {
    january: {
        title: "January",
        messages: {
            1: "Сайхан амарна"
        }
    },
    february: {
        title: "February",
        messages: {
            1: "Сагсны тэмцээнтэй",
            3: "Шагнал гардуулна даа",
            17: "Жавхлан багшийн лаб 2-ыг хийнэ"
        }
    },
    march: {
        title: "March",
        messages: {
            2: "Энэ лабынхаа хугацааг сунгах уу яах вэ гэдэгээ шийднэ",
            6: "Энд юу бичье дээ байз",
            8: "Эмэгтэйчүүддээ баяр хүргэнэ дээ"
        }
    },
    april: {
        title: "April",
        messages: {
            1: "Бүгдээрээ худлаа ярьцаагаагаарай"
        }
    },
    may: {
        title: "May",
        messages: {
            10: "Энэ сард ч ёстой юу ч болдоггүй сар даа"
        }
    },
    june: {
        title: "June",
        messages: {
            6: "Жавхлан багшийн төрсөн өдөр"
        }
    },
    july: {
        title: "July",
        messages: {
            4: "Хичээл амарсаан ураа"
        }
    },
    august: {
        title: "August",
        messages: {
            1: "Хөдөө явдаг цаг даа",
            25: "Хичээл сонголт эхэллээ"
        }
    },
    september: {
        title: "September",
        messages: {
            1: "9-н сарын нэгэн боллоо ерөөсөө бидний баяр даа"
        }
    },
    october: {
        title: "October",
        messages: {
            13: "Сур сур бас дахин сур"
        }
    },
    november: {
        title: "November",
        messages: {
            2: "Сурсаар л бай"
        }
    },
    december: {
        title: "December",
        messages: {
            20: "Өвлийн семистер хаагдах нь дээ",
            30: "Дүн гаргаж дууслаа баярлалаа баяртай"
        }
    }
}

function start() {
    const container = document.querySelector('#events');
    const list = document.createElement("ul");

    const data = Object.values(calendar_data);

    for (let month of data) {
        const monthItem = document.createElement("li");
        const innerList = document.createElement("ul");

        monthItem.append(month.title);

        const messagesData = Object.entries(month.messages);

        for (let [key, message] of messagesData) {
            const messageItem = document.createElement("li");

            messageItem.append(`${key} ${message}`);
            innerList.append(messageItem);
        }

        monthItem.append(innerList);
        list.append(monthItem);
    }

    container.append(list);
}

start();

Sign up to request clarification or add additional context in comments.

Comments

1

Giving you a straight answer : monthNames[i] == 1 will never be true . monthNames[i] returns the value of the monthNames array at the position indicated by [i]. That means that can be only one of the values inside monthNames and since you don't have 1 inside that array the if condition is never gonna be true. At least should be if (monthNames[i] == "january").

Said so I suggest you to look at the loop in js for .. of, for..in and forEach otherwise it will be very difficult for you to get the data from calendar_msgs

here you can find info about the for..in

here you can find info about the for..of

here you can find info about the forEach

With those you can do something like this

But as someone else suggested is maybe better that you change the structure of your data.

2 Comments

PS. there is a space after the word January on the first array change "January " with "January"
Yeah, I see. That was indeed foolish of me to think that "monthNames[i]" would have a numeric value.
1

Here's a solution with plenty of comments to explain what's going on. It loops through the calendar_msgs data instead of the monthNames array, so it relies on that data including a property for each of the 12 months (but the value can be just an empty object if there are no messages for that month -- I commented out the message for April to show how this works.)

I used the Object.keys(), Object.values(), and Array.prototype.forEach() methods, so check them out on MDN if you're unfamiliar with them.

eventList();

// Main function
function eventList() {

  const
    // Retrieves data structures definining months and messages
    monthNames = getMonthNames(),
    calendar_msgs = getCalendarMsgs(),

    // Identifies an existing div, and creates a ul that will eventually go in it
    eventsDiv = document.getElementById("events"),
    monthsUL = document.createElement("ul");
  
  // Loops through the 12 values of the msgs object -- each is a monthObj
  // (Each monthObj looks like `{ jan: { 1: "xxx", 4: "yyy" }}`; value can be empty)
  Object.values(calendar_msgs).forEach( (monthObj, index) => {

    // Each month-specific li will contain the monthName and a monthMsgsUL
    const monthLI = document.createElement("li");

    // (Assumes the correct monthName can be found at the same index as monthObj)
    monthLI.innerHTML = monthNames[index];

    // Makes the monthMsgsUL, and populates it with LIs containing msgs
    const monthMsgsUL = document.createElement("ul");

    // (Each msg is stored in a prop of monthObj w/ dateOfMonth as its key)
    for (let dateOfMonth of Object.keys(monthObj)){

      // Makes li for msg, builds content from prop name and value, & adds li to monthUL
      const msgLI = document.createElement("li");
      msgLI.innerHTML = `${dateOfMonth} : ${monthObj[dateOfMonth]}`;
      monthMsgsUL.appendChild(msgLI);
    }
    
    // If monthObj included any props, adds msgs ul to month and month to monthsUL
    if(monthMsgsUL.children.length){
      monthLI.appendChild(monthMsgsUL);
      monthsUL.appendChild(monthLI);
    }
  });
  // New content is complete and gets added to the DOM
  eventsDiv.appendChild(monthsUL);
}

// Just gives us the array of month names
function getMonthNames(){
  return ["January ", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
}

// Just gives us the data structure that defines the messages
function getCalendarMsgs(){
  return {
    jan: {
      1: "Сайхан амарна"
    },
    feb: {
      1: "Сагсны тэмцээнтэй",
      3: "Шагнал гардуулна даа",
      17: "Жавхлан багшийн лаб 2-ыг хийнэ"
    },
    mar: {
      2: "Энэ лабынхаа хугацааг сунгах уу яах вэ гэдэгээ шийднэ",
      6: "Энд юу бичье дээ байз",
      8: "Эмэгтэйчүүддээ баяр хүргэнэ дээ"
    },
    apr: { // NOTE: All 12 months MUST be included (but they may be empty)
      /* 1: "Бүгдээрээ худлаа ярьцаагаагаарай" */
    },
    may: {
      10: "Энэ сард ч ёстой юу ч болдоггүй сар даа"
    },
    jun: {
      6: "Жавхлан багшийн төрсөн өдөр"
    },
    jul: {
      4: "Хичээл амарсаан ураа"
    },
    aug: {
      1: "Хөдөө явдаг цаг даа",
      25: "Хичээл сонголт эхэллээ"
    },
    sep: {
      1: "9-н сарын нэгэн боллоо ерөөсөө бидний баяр даа"
    },
    oct: {
      13: "Сур сур бас дахин сур"
    },
    nov: {
      2: "Сурсаар л бай"
    },
    dec: {
      20: "Өвлийн семистер хаагдах нь дээ",
      30: "Дүн гаргаж дууслаа баярлалаа баяртай"
    }
  };
}
<h1 id="year">2021 Calendar</h1>
<div id="events"><h2>Events</h2></div>

I think in your original code, you might have defined a variable in the wrong scope (eg before a loop instead of inside it) and/or used a variable without first declaring it (eg with const or let) -- although I'm not 100% certain I'm remembering this correctly. Anyway, those are good pitfalls to avoid, regardless.

EDIT: As others have pointed out, if you have control over the structure of the original data, it might be good to structure it differently because that could allow you to process it using simpler code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.