Event Bubbling in Javascript

With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements. With capturing, the process is in reverse. We usually attach an event to a handler using the addEventListener function.

addEventListener("click", handler, useCapture=false)

The third argument useCapture is the key. The default value is false. So, it will be a bubbling model where the event is handled by the innermost element first and it propagates outwards till it reaches the parent element. If that argument is true, it is capturing model.

<div onClick="divHandler()">
    <ul onClick="ulHandler">
        <li id="foo"></li>
    </ul>
</div>
<script>
function handler() {
 // do something here
}
function divHandler(){}
function ulHandler(){}
document.getElementById("foo").addEventListener("click", handler)
</script>

When we click the list element, the order of execution of handlers is like this in bubbling (default) model.

handler() => ulHandler() => divHandler()

Hoisting in Javascript

Hoisting is a process of pushing the declared variables to the top of the program while running it. For Ex:

doSomething(foo); // used before
var foo; // declared later

 In this mechanism, a JavaScript VM does two things while running a program:

  1. First scan the program, collect all the variable and function declarations and assign memory spaces for it.
  2. Run the program now by filling variable values assigned any, if not, fill undefined

In the above code snippet, console.log prints “undefined”. It is because in the first pass variable foo is collected. VM looks for any value defined for variable foo. This hoisting can result in many JavaScript code situations where code can throw errors in some places and uses undefined silently in another. You should be knowing hoisting to clear the ambiguity! See a few examples!

HTML Response Status Codes

  1. Information Response – starts with 100
  2. Successful Response – starts with 200 (200 success ok)
  3. Redirection Messages – starts with 300
  4. Client Error Response – starts with 400 (404 Not found is important)
  5. Server Error Response – starts with 500

Add Two Numbers – Leetcode Solution

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4 )
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        newList = ListNode(self)
        temp = newList
        
        carry =0
        sumTotal = 0
        
        while l1 or l2 or carry:
            if l1:
                sumTotal =  sumTotal+ l1.val
                l1 = l1.next
            if l2:
                sumTotal = sumTotal + l2.val
                l2 = l2.next
            sumTotal = sumTotal + carry
            carry  = sumTotal//10
            temp.next = ListNode(sumTotal%10)
            sumTotal = 0
            temp  = temp.next
        
        return newList.next

Meeting Rooms – Leetcode Solution

Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings.

Example 1:

Input: [[0,30],[5,10],[15,20]]
Output: false

Example 2:

put: [[7,10],[2,4]]
Output: True
class Solution:
    def canAttendMeetings(self, intervals: List[List[int]]) -> bool:
        start = 0
        end = 1
        intervals.sort()
        print(intervals)
        for i in range(1, len(intervals)):
            if intervals[i][start] < intervals[i-1][end]:
                return False

        return True

Two Sum – Leetcode Solution

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given mums = [2,7,11,15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0,1]

def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                add = nums[i] + nums[j]
                if(add == target):
                    sums = [i,j]
        return sums

Address Book – Javascript

Address Book

HTML:

<!doctype html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<title>AddressBook</title>
	<link rel="stylesheet" href="addressbook.css">
	<script src="addressbook.js"></script>
</head>

<body>
	<div class="container">
		<div class="addForm panel">
			<h1>Address Book</h1>
			<label for="fullname" class="labelForm">Name</label>
			<input type="text" id="fullname" class="formFields" placeholder="Enter your name">
			<label for="phone" class="labelForm">Phone Number</label>
			<input type="text" id="phone" class="formFields" placeholder="Phone">
			<label for="email" class="labelForm">Email</label>
			<input type="text" id="email" class="formFields" placeholder="Email Here">
			<br>
			<br>
			<button id="add" class="button-blue">Add Contact</button>
		</div>
		<div class="contactList">
			<h1>Contact List</h1>
			<div class="addbook">
				<div class="entry">
					<div class="name"><p></p></div>
					<div class="email"><p></p></div>
					<div class="phone"><p></p></div>
					<div class="del"><a href="#">Delete</a></div>
				</div>
			</div>
		</div>
	</div>
</body>

</html>

CSS

.panel {
    background: #8dcb66;
    padding: 1em;
    width: 92.5%;
    margin: auto;
    max-width: 30em;
    color: white;
}

input {
    width: 100%;
    box-sizing: border-box;
    font-size: 1em;
    margin: 0.5em;
    padding: 0.5em;
}

label {
    width: 100%;
    font-size: 1em;
    padding: 10px;
}

button {
    text-align: center;
    border-radius: 3px;
    cursor: pointer;
    display: inline-block;
    font-family: Verdana, sans-serif;
    font-size: 12px;
    font-weight: 400;
    line-height: 20px;
    padding: 9px 16px 9px;
    margin: 16px 0 0 16px;
    transition: all 20ms ease-out;
    vertical-align: top;
}

.addbook {
    margin: 20px;
}

.contactList {
    background: #7f74ba;
    color: white;
    margin: 2px;
    padding: 5px;
    text-align: center;
}

.entry {
    border-radius: 3px;
    height: 40px;
    border-bottom: 1px solid;
    border-top: 1px solid;
    color: white;
    padding: 10px;
}

.entry .name {
    width: 300px;
    float: left;
    padding: 11px;
}

.entry .email {
    width: 300px;
    float: left;
    padding: 11px;
}

.entry .phone {
    width: 300px;
    float: left;
    padding: 11px;
    padding-right: 30px;
}

.entry .del {
    width: 40px;
    float: right;
    padding: 9px;
    margin-right: 30px;
}

.entry p {
    margin: 0px;
    font-family: Verdana, sans-serif;
    font-size: 12px;
}

.entry .del a {
    border-radius: 10px;
    cursor: pointer;
    font-family: Verdana, sans-serif;
    color: #FFF;
    font-size: 12px;
    padding: 8px;
    background: rgb(255, 100, 100);
    text-decoration: none;
}

.button-blue {
    background-color: #42b0e3;
    background-image: linear-gradient(to bottom, #42b0e3, #2ba9e3);
    border: 1px solid #107db0;
    box-shadow: inset 0 1px 0 #7cd4fc, inset 0 -1px 0 #2696c9, inset 0 0 0 1px #59b7e3, 0 2px 4px rgba(0, 0, 0, 0.2);
    color: white;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.h2 {
    font-family: Verdana, sans-serif;
    color: white;
}

JavaScript

window.onload = function () {
    //buttons
    var addBtn = document.getElementById("add");
    var addFormDiv = document.querySelector(".addForm");

    //form fields:
    var fullname = document.getElementById("fullname");
    var phone = document.getElementById("phone");
    var email = document.getElementById("email");

    //address book display
    var addBookdiv = document.querySelector(".addbook");

    //Intialize storage array
    var dataArray = [];

    //eventListeners
    addBtn.addEventListener("click", addToBook);
    addBookdiv.addEventListener("click", removeContact);

    function structure(fullname, phone, email) {
        this.fullname = fullname;
        this.phone = phone;
        this.email = email;
    }

    function addToBook() {
        //test if fields are empty
        var testIfempty = fullname.value != '' && phone.value != '' && email.value != '';
        //console.log(testIfempty);

        if (testIfempty) {
            //add contents to array and add contents to localstorage
            var obj = new structure(fullname.value, phone.value, email.value);
            dataArray.push(obj);
            localStorage['contactInfo'] = JSON.stringify(dataArray);

            //clear form
            clearForm();

            //update display from the form data collected
            displayContactInfo();
        }

    }

    function clearForm() {
        var filledForm = document.querySelectorAll(".formFields");
        for (var i in filledForm) {
            filledForm[i].value = "";
        }
    }

    function removeContact(e) {
        if (e.target.classList.contains("removeButton")) {
            var rmId = e.target.getAttribute("data-id");

            dataArray.splice(rmId, 1);
            //update localstorage
            localStorage['contactInfo'] = JSON.stringify(dataArray);
            displayContactInfo();
        }
    }

    function displayContactInfo() {
        //look for localstorage key if not present create it
        //if exists load content from LS and loop it on page for div to populate

        if (localStorage['contactInfo'] === undefined) {
            localStorage['contactInfo'] = "[]" //string
        } else {
            dataArray = JSON.parse(localStorage['contactInfo']);
            addBookdiv.innerHTML = '';
            for (var i in dataArray) {
                var str = '<div class="entry">';
                str += '<div class="name"><p>' + dataArray[i].fullname + '</p></div>';
                str += '<div class="email"><p>' + dataArray[i].email + '</p></div>';
                str += '<div class="phone"><p>' + dataArray[i].phone + '</p ></div>';
                str += '<div class="del"><a href="#" class="removeButton" data-id="' + i + '" >Delete</a></div>';
                str += '</div >';
                addBookdiv.innerHTML += str;
            }
        }
    }

    displayContactInfo();
}

Notes:

The read-only localStorage property allows you to access Storage object for the Document‘s origin; the stored data is saved across browser sessions. localStorage is similar to sessionStorage, except that while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the page session ends — that is, when the page is closed.

**The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).**

Reference : Click Here