kthornbloom / Monthly

A jQuery based responsive calendar
http://kthornbloom.com/monthly/
Other
316 stars 108 forks source link

Getting the clicked day #67

Closed arucuenca closed 7 years ago

arucuenca commented 7 years ago

Is there a way to do it and if so, how do I get the value of the day the user clicked?

ghost commented 7 years ago

Aruan, you will find this code in the monthly.js file:

$(document.body).on("click touchstart", parent + " .monthly-day", function (event) { // If events, show events list var whichDay = $(this).data("number"); ...

whichDay then holds the day of the month. Is that what you're looking for?

On Tue, Jun 27, 2017 at 03:18:37PM -0700, Aruan Cuenca Carrara wrote:

Is there a way to do it and if so, how do I get the value of the day the user clicked?

-- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/kthornbloom/Monthly/issues/67

arucuenca commented 7 years ago

Yes, I got the day, but if I try to get this value out of that method, I can't get the same result.

The original function, that prints the correct day. $(document.body).on("click touchstart", parent + " .monthly-day", function (event) { var whichDay = $(this).data("number"); console.log(whichDay);

And the function I'm trying to create, that get "undefined" $(document.getElementsByClassName("monthly-event-list")).dblclick(parent + " .monthly-day", function () { var thisDay= $(this).data("number"); console.log(thisDay);

ghost commented 7 years ago

Oh, then I'm not sure. If you send me the whole monthly.js, I could see if I can figure it out, but I'm not an expert. :smile:

arucuenca commented 7 years ago

Yeah, I'm a beginner, so anything I can learn from you is profit. Btw, here's my monthly.js `/ Monthly 2.2.1 by Kevin Thornbloom is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. /

(function ($) { "use strict"; $.fn.extend({ monthly: function(customOptions) {

        // These are overridden by options declared in footer
        var defaults = {
            dataType: "xml",
            disablePast: false,
            eventList: true,
            events: "",
            jsonUrl: "",
            linkCalendarToEventUrl: false,
            maxWidth: false,
            mode: "event",
            setWidth: false,
            showTrigger: "",
            startHidden: false,
            stylePast: false,
            target: "",
            useIsoDateFormat: false,
            weekStart: 0,   // Sunday
            xmlUrl: ""
        };

        var options = $.extend(defaults, customOptions),
            uniqueId = $(this).attr("id"),
            parent = "#" + uniqueId,
            currentDate = new Date(),
            currentMonth = currentDate.getMonth() + 1,
            currentYear = currentDate.getFullYear(),
            currentDay = currentDate.getDate(),
            locale = (options.locale || defaultLocale()).toLowerCase(),
            monthNameFormat = options.monthNameFormat || "short",
            weekdayNameFormat = options.weekdayNameFormat || "short",
            monthNames = options.monthNames || defaultMonthNames(),
            dayNames = options.dayNames || defaultDayNames(),
            markupBlankDay = '<div class="m-d monthly-day-blank"><div class="monthly-day-number"></div></div>',
            weekStartsOnMonday = options.weekStart === "Dom" || options.weekStart === 1 || options.weekStart === "1",
            primaryLanguageCode = locale.substring(0, 2).toLowerCase();

    if (options.maxWidth !== false) {
        $(parent).css("maxWidth", options.maxWidth);
    }
    if (options.setWidth !== false) {
        $(parent).css("width", options.setWidth);
    }

    if (options.startHidden) {
        $(parent).addClass("monthly-pop").css({
            display: "none",
            position: "absolute"
        });
        $(document).on("focus", String(options.showTrigger), function (event) {
            $(parent).show();
            event.preventDefault();
        });
        $(document).on("click", String(options.showTrigger) + ", .monthly-pop", function (event) {
            event.stopPropagation();
            event.preventDefault();
        });
        $(document).on("click", function () {
            $(parent).hide();
        });
    }

    // Add Day Of Week Titles
    _appendDayNames(weekStartsOnMonday);

    // Add CSS classes for the primary language and the locale. This allows for CSS-driven
    // overrides of the language-specific header buttons. Lowercased because locale codes
    // are case-insensitive but CSS is not.
    $(parent).addClass("monthly-locale-" + primaryLanguageCode + " monthly-locale-" + locale);

    // Add Header & event list markup
    $(parent).prepend('<div class="monthly-header"><div class="monthly-header-title"><a href="#" class="monthly-header-title-date" onclick="return false"></a></div><a href="#" class="monthly-prev"></a><a href="#" class="monthly-next"></a></div>').append('<div class="monthly-event-list"></div>');

    // Set the calendar the first time
    setMonthly(currentMonth, currentYear);

    // How many days are in this month?
    function daysInMonth(month, year) {
        return month === 2 ? (year & 3) || (!(year % 25) && year & 15) ? 28 : 29 : 30 + (month + (month >> 3) & 1);
    }

    // Build the month
    function setMonthly(month, year) {
        $(parent).data("setMonth", month).data("setYear", year);

        // Get number of days
        var index = 0,
            dayQty = daysInMonth(month, year),
            // Get day of the week the first day is
            mZeroed = month - 1,
            firstDay = new Date(year, mZeroed, 1, 0, 0, 0, 0).getDay(),
            settingCurrentMonth = month === currentMonth && year === currentYear;

        // Remove old days
        $(parent + " .monthly-day, " + parent + " .monthly-day-blank").remove();
        $(parent + " .monthly-event-list, " + parent + " .monthly-day-wrap").empty();
        // Print out the days
        for(var dayNumber = 1; dayNumber <= dayQty; dayNumber++) {
            // Check if it's a day in the past
            var isInPast = options.stylePast && (
                year < currentYear
                || (year === currentYear && (
                    month < currentMonth
                    || (month === currentMonth && dayNumber < currentDay)
                ))),
                innerMarkup = '<div class="monthly-day-number">' + dayNumber + '</div><div class="monthly-indicator-wrap"></div>';
            if(options.mode === "event") {
                var thisDate = new Date(year, mZeroed, dayNumber, 0, 0, 0, 0);
                $(parent + " .monthly-day-wrap").append("<div"
                    + attr("class", "m-d monthly-day monthly-day-event"
                        + (isInPast ? " monthly-past-day" : "")
                        + " dt" + thisDate.toISOString().slice(0, 10)
                        )
                    + attr("data-number", dayNumber)
                    + ">" + innerMarkup + "</div>");
                $(parent + " .monthly-event-list").append("<div"
                    + attr("class", "monthly-list-item")
                    + attr("id", uniqueId + "day" + dayNumber)
                    + attr("data-number", dayNumber)
                    + '><div class="monthly-event-list-date">' + dayNames[thisDate.getDay()] + "<br>" + dayNumber + "</div></div>");
            } else {
                $(parent + " .monthly-day-wrap").append("<a"
                    + attr("href", "#")
                    + attr("class", "m-d monthly-day monthly-day-pick" + (isInPast ? " monthly-past-day" : ""))
                    + attr("data-number", dayNumber)
                    + ">" + innerMarkup + "</a>");
            }
        }

        if (settingCurrentMonth) {
            $(parent + ' *[data-number="' + currentDay + '"]').addClass("monthly-today");
        }

        // Reset button
        $(parent + " .monthly-header-title").html(
            '<a href="#" class="monthly-header-title-date" onclick="return false">' + monthNames[month - 1] + " " + year + "</a>"
            + (settingCurrentMonth ? "" : '<a href="#" class="monthly-reset"></a>'));

        // Account for empty days at start
        if(weekStartsOnMonday) {
            if (firstDay === 0) {
                _prependBlankDays(6);
            } else if (firstDay !== 1) {
                _prependBlankDays(firstDay - 1);
            }
        } else if(firstDay !== 7) {
            _prependBlankDays(firstDay);
        }

        // Account for empty days at end
        var numdays = $(parent + " .monthly-day").length,
            numempty = $(parent + " .monthly-day-blank").length,
            totaldays = numdays + numempty,
            roundup = Math.ceil(totaldays / 7) * 7,
            daysdiff = roundup - totaldays;
        if(totaldays % 7 !== 0) {
            for(index = 0; index < daysdiff; index++) {
                $(parent + " .monthly-day-wrap").append(markupBlankDay);
            }
        }

        // Events
        if (options.mode === "event") {
            addEvents(month, year);
        }
        var divs = $(parent + " .m-d");
        for(index = 0; index < divs.length; index += 7) {
            divs.slice(index, index + 7).wrapAll('<div class="monthly-week"></div>');
        }
    }

    function addEvent(event, setMonth, setYear) {
        // Year [0]   Month [1]   Day [2]
        var fullStartDate = _getEventDetail(event, "startdate"),
            fullEndDate = _getEventDetail(event, "enddate"),
            startArr = fullStartDate.split("-"),
            startYear = parseInt(startArr[2], 10),
            startMonth = parseInt(startArr[1], 10),
            startDay = parseInt(startArr[0], 10),
            startDayNumber = startDay,
            endDayNumber = startDay,
            showEventTitleOnDay = startDay,
            startsThisMonth = startMonth === setMonth && startYear === setYear,
            happensThisMonth = startsThisMonth;

        if(fullEndDate) {
            // If event has an end date, determine if the range overlaps this month
            var endArr = fullEndDate.split("-"),
                endYear = parseInt(endArr[2], 10),
                endMonth = parseInt(endArr[1], 10),
                endDay = parseInt(endArr[0], 10),
                startsInPastMonth = startYear < setYear || (startMonth < setMonth && startYear === setYear),
                endsThisMonth = endMonth === setMonth && endYear === setYear,
                endsInFutureMonth = endYear > setYear || (endMonth > setMonth && endYear === setYear);
            if(startsThisMonth || endsThisMonth || (startsInPastMonth && endsInFutureMonth)) {
                happensThisMonth = true;
                startDayNumber = startsThisMonth ? startDay : 1;
                endDayNumber = endsThisMonth ? endDay : daysInMonth(setMonth, setYear);
                showEventTitleOnDay = startsThisMonth ? startDayNumber : 1;
            }
        }
        if(!happensThisMonth) {
            return;
        }

        var startTime = _getEventDetail(event, "starttime"),
            timeHtml = "",
            eventLocal = _getEventDetail(event, "local"),
            eventMat = _getEventDetail(event, "materiais"),
                            eventTitle = _getEventDetail(event, "name"),
            eventClass = _getEventDetail(event, "class"),
            eventColor = _getEventDetail(event, "color"),
            eventId = _getEventDetail(event, "id"),
            customClass = eventClass ? " " + eventClass : "",
            dayStartTag = "<div",
            dayEndTags = "</span></div>";

        if(startTime) {
            var endTime = _getEventDetail(event, "endtime");
            timeHtml = '<div><div class="monthly-list-time-start">'+ "Horário: " + formatTime(startTime) + "</div>"
                + (endTime ? '<div class="monthly-list-time-end">' + formatTime(endTime) + "</div>" : "")
                + "</div>";
        }

        var markupDayStart = dayStartTag
                + attr("data-eventid", eventId)
                + attr("title", eventTitle)
                // BG and FG colors must match for left box shadow to create seamless link between dates
                + (eventColor ? attr("style", "background:" + eventColor + ";color:" + eventColor) : ""),
            markupListEvent = "<box"
                + attr("class", "listed-event" + customClass)
                + attr("data-eventid", eventId)
                + (eventColor ? attr("style", "background:" + eventColor) : "")
                + attr("title", eventTitle)                                        
                + ">" + eventTitle + "<br>" + "Local: " + eventLocal +"<br>"+ "Materiais: " + eventMat +"<br>" + timeHtml + "</box>";
        for(var index = startDayNumber; index <= endDayNumber; index++) {
            var doShowTitle = index === showEventTitleOnDay;
            // Add to calendar view
            $(parent + ' *[data-number="' + index + '"] .monthly-indicator-wrap').append(
                    markupDayStart
                    + attr("class", "monthly-event-indicator" + customClass
                        // Include a class marking if this event continues from the previous day
                        + (doShowTitle ? "" : " monthly-event-continued")
                        )
                    + "><span>" + (doShowTitle ? eventTitle : "") + dayEndTags);
            // Add to event list
            $(parent + ' .monthly-list-item[data-number="' + index + '"]')
                .addClass("item-has-event")
                .append(markupListEvent);
        }
    }

    function addEvents(month, year) {
        if(options.events) {
            // Prefer local events if provided
            addEventsFromString(options.events, month, year);
        } else {
            var remoteUrl = options.dataType === "xml" ? options.xmlUrl : options.jsonUrl;
            if(remoteUrl) {
                // Replace variables for month and year to load from dynamic sources
                var url = String(remoteUrl).replace("{month}", month).replace("{year}", year);
                $.get(url, {now: $.now()}, function(data) {
                    addEventsFromString(data, month, year);
                }, options.dataType).fail(function() {
                    console.error("Não foi possível carregar o arquivo. " + remoteUrl + " Por favor insira local e sintaxe corretos. " + options.dataType);
                });
            }
        }
    }

    function addEventsFromString(events, setMonth, setYear) {
        if (options.dataType === "xml") {
            $(events).find("event").each(function(index, event) {
                addEvent(event, setMonth, setYear);
            });
        } else if (options.dataType === "json") {
            $.each(events.monthly, function(index, event) {
                addEvent(event, setMonth, setYear);
            });
        }
    }

    function attr(name, value) {
        var parseValue = String(value);
        var newValue = "";
        for(var index = 0; index < parseValue.length; index++) {
            switch(parseValue[index]) {
                case "'": newValue += "&#39;"; break;
                case "\"": newValue += "&quot;"; break;
                case "<": newValue += "&lt;"; break;
                case ">": newValue += "&gt;"; break;
                default: newValue += parseValue[index];
            }
        }
        return " " + name + "=\"" + newValue + "\"";
    }

    function _appendDayNames(startOnMonday) {
        var offset = startOnMonday ? 1 : 0,
            dayName = "",
            dayIndex = 0;
        for(dayIndex = 0; dayIndex < 6; dayIndex++) {
            dayName += "<div>" + dayNames[dayIndex + offset] + "</div>";
        }
        dayName += "<div>" + dayNames[startOnMonday ? 0 : 6] + "</div>";
        $(parent).append('<div class="monthly-day-title-wrap">' + dayName + '</div><div class="monthly-day-wrap"></div>');
    }

    // Detect the user's preferred language
    function defaultLocale() {
        if(navigator.languages && navigator.languages.length) {
            return navigator.languages[0];
        }
        return navigator.language || navigator.browserLanguage;
    }

    // Use the user's locale if possible to obtain a list of short month names, falling back on English
    function defaultMonthNames() {
        if(typeof Intl === "undefined") {
            return ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];
        }
        var formatter = new Intl.DateTimeFormat(locale, {month: monthNameFormat});
        var names = [];
        for(var monthIndex = 0; monthIndex < 12; monthIndex++) {
            var sampleDate = new Date(2017, monthIndex, 1, 0, 0, 0);
            names[monthIndex] = formatter.format(sampleDate);
        }
        return names;
    }

    function formatDate(year, month, day) {
        if(options.useIsoDateFormat) {
            return new Date(year, month - 1, day, 0, 0, 0).toISOString().substring(0, 10);
        }
        if(typeof Intl === "undefined") {
            return month + "/" + day + "/" + year;
        }
        return new Intl.DateTimeFormat(locale).format(new Date(year, month - 1, day, 0, 0, 0));
    }

    // Use the user's locale if possible to obtain a list of short weekday names, falling back on English
    function defaultDayNames() {
        if(typeof Intl === "undefined") {
            return ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"];
        }
        var formatter = new Intl.DateTimeFormat(locale, {weekday: weekdayNameFormat}),
            names = [],
            dayIndex = 0,
            sampleDate = null;
        for(dayIndex = 0; dayIndex < 7; dayIndex++) {
            // 2017 starts on a Sunday, so use it to capture the locale's weekday names
            sampleDate = new Date(2017, 0, dayIndex + 1, 0, 0, 0);
            names[dayIndex] = formatter.format(sampleDate);
        }
        return names;
    }

    function _prependBlankDays(count) {
        var wrapperEl = $(parent + " .monthly-day-wrap"),
            index = 0;
        for(index = 0; index < count; index++) {
            wrapperEl.prepend(markupBlankDay);
        }
    }

    function _getEventDetail(event, nodeName) {
        return options.dataType === "xml" ? $(event).find(nodeName).text() : event[nodeName];
    }

    // Returns a 12-hour format hour/minute with period. Opportunity for future localization.
    function formatTime(value) {
        var timeSplit = value.split(":");
        var hour = parseInt(timeSplit[0], 10);
        var period = "Manhã";
        if(hour > 12) {
            hour -= 12;
            period = "Tarde";
        } else if (hour === 12) {
            period = "Tarde";
        } else if(hour === 0) {
            hour = 12;
        }
        return hour + ":" + String(timeSplit[1]) + " " + period;
    }

    function setNextMonth() {
        var setMonth = $(parent).data("setMonth"),
            setYear = $(parent).data("setYear"),
            newMonth = setMonth === 12 ? 1 : setMonth + 1,
            newYear = setMonth === 12 ? setYear + 1 : setYear;
        setMonthly(newMonth, newYear);
        viewToggleButton();
    }

    function setPreviousMonth() {
        var setMonth = $(parent).data("setMonth"),
            setYear = $(parent).data("setYear"),
            newMonth = setMonth === 1 ? 12 : setMonth - 1,
            newYear = setMonth === 1 ? setYear - 1 : setYear;
        setMonthly(newMonth, newYear);
        viewToggleButton();
    }

    // Function to go back to the month view
    function viewToggleButton() {
        if($(parent + " .monthly-event-list").is(":visible")) {
            $(parent + " .monthly-cal").remove();
            $(parent + " .monthly-header-title").prepend('<a href="#" class="monthly-cal"></a>');
        }
    }

    // Advance months
    $(document.body).on("click", parent + " .monthly-next", function (event) {
        setNextMonth();
        event.preventDefault();
    });

    // Go back in months
    $(document.body).on("click", parent + " .monthly-prev", function (event) {
        setPreviousMonth();
        event.preventDefault();
    });

    // Reset Month
    $(document.body).on("click", parent + " .monthly-reset", function (event) {
        $(this).remove();
        setMonthly(currentMonth, currentYear);
        viewToggleButton();
        event.preventDefault();
        event.stopPropagation();
    });

    // Back to month view
    $(document.body).on("click", parent + " .monthly-cal", function (event) {
        $(this).remove();
        $(parent + " .monthly-event-list").css("transform", "scale(1)");
        setTimeout(function() {
            $(parent + " .monthly-event-list").hide();
        }, 250);
        event.preventDefault();
    });

    // Click A Day
    $(document.body).on("click touchstart", parent + " .monthly-day", function (event) {
        // If events, show events list
        var whichDay = $(this).data("number");
                    console.log(whichDay);
        if(options.mode === "event" && options.eventList) {
            var theList = $(parent + " .monthly-event-list"),
                myElement = document.getElementById(uniqueId + "day" + whichDay),
                topPos = myElement.offsetTop;
            theList.show();
            theList.css("transform");
            theList.css("transform", "scale(1)");
            $(parent + ' .monthly-list-item[data-number="' + whichDay + '"]').show();
            theList.scrollTop(topPos);
            viewToggleButton();
            if(!options.linkCalendarToEventUrl) {
                event.preventDefault();
            }
        // If picker, pick date
        } else if (options.mode === "picker") {
            var setMonth = $(parent).data("setMonth"),
                setYear = $(parent).data("setYear");
            // Should days in the past be disabled?
            if($(this).hasClass("monthly-past-day") && options.disablePast) {
                // If so, don't do anything.
                event.preventDefault();
            } else {
                // Otherwise, select the date ...
                $(String(options.target)).val(formatDate(setYear, setMonth, whichDay));
                // ... and then hide the calendar if it started that way
                if(options.startHidden) {
                    $(parent).hide();
                }
            }
            event.preventDefault();
        }
    });
            $(document.getElementsByClassName("monthly-event-list")).dblclick(parent + " .monthly-day", function () {                        
                var thisDay= $(this).data("number");
                console.log(thisDay);
                $("#startdate").val("2017-06-"+thisDay);    
                $("#novoEvento").modal({backdrop: true});
            });

    // Clicking an event within the list
    $(document.body).on("click", parent + " .listed-event", function (event) {
        var href = $(this).attr("href");
        // If there isn't a link, don't go anywhere
        if(!href) {
            event.preventDefault();
        }
    });

}
});

}(jQuery)); `

ghost commented 7 years ago

I'm not sure. I didn't have much luck getting the number out, but you can find the date in the hierarchy output in the javascript console from adding this line in your function:

console.log("this:",$(this));

If you have selected the 8th day of the month, for example, you will find:

...
innerText: "Thu↵8↵"
...

somewhere down in the hierarchy, and I think you could extract it. That's all I was able to figure out.

arucuenca commented 7 years ago

I think I figured out the problem. The element I'm selecting is "monthly-event-list", which (I believe) has no access to "number", that is an attribute from "monthly-day". Maybe that's the reason I get the "undefined", and I'll try to find a way to get the number from another way.

arucuenca commented 7 years ago

Got this working this way: $(document.getElementsByClassName("monthly-event-list")).dblclick(function () { if(whichDay<10){ var dia = "0"+whichDay; }else{ var dia = whichDay;} $("#startdate").val("2017-06-"+dia); console.log(dia); $("#novoEvento").modal({backdrop: true}); }); I moved my function to inside the simple-click one and I receive the data it gets when called.

ghost commented 7 years ago

Excellent. :+1:

arucuenca commented 7 years ago

Thank you for the help!