/ Gists

Gists

On gists

Custom event (flash event ;).

Alpine.js

index.html #

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Alpine Examples</title>

    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"
            defer
    ></script>

    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
          rel="stylesheet"
    >
</head>

<body class="p-12">
    <!-- Flash -->
    <div
        x-data="{ show: false, message: '' }"
        x-show.transition.opacity.scale.75.duration="show"
        @flash.window="
            show = true;
            message = $event.detail;
            setTimeout(() => show = false, 3000);
        "
        x-text="message"
        class="fixed bottom-0 right-0 mb-4 mr-4 bg-blue-500 text-white p-4 rounded"
    >

    </div>

    <script>
        // Additionally, any component can call $dispatch('flash', 'A flash message');

        window.flash = message => window.dispatchEvent(new CustomEvent('flash', {detail: message}));
    </script>
</body>

</html>

On gists

Struktura tabulky

AW

struct.php #

<?php
		$description = $this->connection->table('customer_address')->getStructure();
		$description->getCols();

On gists

Remove via $event / $el

Alpine.js

remove.html #

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="//unpkg.com/alpinejs" defer></script>
</head>
<body>
  <div x-data>
      <button @click="$el.remove()">remove me 1</button>
      <button @click="$event.target.remove()">remove me 2</button>
  </div>
</body>
</html>

On gists

Change something via 3 ways ($refs, $el, $nextTick)

Alpine.js

index.html #

<div x-data>
  <span x-ref="foo"></span>
  <button  class="btn btn-dark" @click="$refs.foo.innerText = 'Smashing Magazine'">Click me</button>
</div>

<div x-data>
  <button  class="btn btn-secondary" @click="$el.innerHTML = 'Smashing Magazine'">Click me</button>
</div>

<div x-data="{ text: 'Click me' }">
  <button class="btn btn-primary" @click="
            text = 'Clicked';
            $nextTick(() => {
                    // This will output 'Clicked', not 'Click me'
                    console.log($event.target.innerText) 
            });" x-text="text"></button>
</div>

On gists

Alpine.js - Examples of usage

Alpine.js

index.html #

<div class="container mx-auto mt-6 max-w-sm">
      <h1 class="text-5xl mb-4">Alpine.js Demo</h1>

      <!-- x-data - Declare a new Alpine component and its data for a block of HTML -->
      <div
        x-data="{
        open: false, 
        name: 'Brad',
        search: '',
        posts: [
          {title: 'Post One'},
          {title: 'Post Two'},
          {title: 'Post Three'},
          {title: 'Post Four'},
        ]
      }"
      >
        <!-- x-on - Listen for browser events on an element -->
        <!-- You can also use @click -->
        <!-- x-bind - Dynamically set HTML attributes on an element -->
        <button
          x-on:click="open = !open"
          :class="open ? 'bg-blue-800' : 'bg-slate-700'"
          class="text-white px-4 py-2 rounded-xl"
        >
          Toggle
        </button>

        <!-- x-show - Toggle the visibility of an element-->
        <div x-show="open" x-transition x-cloak>
          <p class="bg-gray-200 p-4 my-6 rounded">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat
            quos laboriosam, minus rerum molestias soluta nisi nulla eos error
            nihil.
          </p>
        </div>

        <!-- x-text - Set the text content of an element / display data -->
        <div class="my-4">
          The value of name is <span x-text="name" class="font-bold"></span>
        </div>

        <!-- x-effect - Execute a script each time one of its dependancies change -->
        <div x-effect="console.log(open)"></div>

        <!-- x-model - Synchronize a piece of data with an input element -->
        <input
          x-model="search"
          type="text"
          class="border p-2 w-full mb-2 mt-6"
          placeholder="Search for something..."
        />
        <p>
          <span class="font-bold">Searching for:</span>
          <span x-text="search"></span>
        </p>

        <!-- x-if - Conditionally add/remove a block of HTML from the page entirely -->
        <template x-if="open">
          <div class="bg-gray-50 p-2 mt-8">Template based on a condition</div>
        </template>

        <!-- x-for - Loop over an array of data -->
        <h3 class="text-2xl mt-6 mb-3 font-bold">Posts</h3>
        <template x-for="post in posts">
          <div x-text="post.title"></div>
        </template>
        <button
          @click="posts.push({title: 'New Post'})"
          class="bg-blue-800 text-white px-4 py-2 rounded-lg mt-4"
        >
          Add Post
        </button>

        <div class="my-6">
          <!-- x-ref - Reference elements directly by their specified keys using the $refs magic property -->
          <div x-ref="text">Hello World</div>

          <button
            @click="$refs.text.remove()"
            class="bg-black text-white p-2 rounded-lg"
          >
            Click
          </button>
        </div>

        <!-- x-html - Set the inner HTML of an element -->
        <div x-html="(await axios.get('./partial.html')).data">...</div>

        <!-- $el - Reference the current DOM element -->
        <button
          x-on:click="$el.innerHTML = 'Hello World'"
          class="mt-4 p-4 border"
        >
          Replace Text
        </button>

        <!-- $watch - Watch a component property -->
        <div x-init="$watch('posts', value => console.log(value))"></div>

        <!-- $dispatch - Shortcut for dispatching browser events -->
        <div @notify="alert('You have been notified!')">
          <button
            @click="$dispatch('notify')"
            class="bg-green-700 text-white p-2 mt-4 rounded-lg"
          >
            Notify
          </button>
        </div>

        <!-- $data - Gives access to current Alpine data scope -->
        <button
          @click="getLatestPost($data.posts)"
          class="bg-orange-800 text-white mt-6 p-2 rounded-lg"
        >
          Get Latest Post
        </button>

        <div class="mt-6">
          <h3 class="text-2xl mb-2">Enter a date:</h3>
          <input
            class="border w-full p-2"
            x-mask="99/99/9999"
            placeholder="MM/DD/YYYY"
          />
        </div>
      </div>
    </div>

<!-- Stores: Dark Mode -->
<div
      x-data
      :class="$store.darkMode.on && 'bg-gray-800 text-white'"
      class="container mx-auto max-w-sm mt-6 bg-gray-50 p-4"
    >
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, reiciendis
      ipsa. Sed, illo, repellat ipsam, perspiciatis soluta labore quasi in eos
      hic harum praesentium perferendis? Dignissimos, unde provident voluptas,
      ad neque ea tempora nam ratione eligendi modi laudantium, iusto officia.

      <button
        @click="$store.darkMode.toggle()"
        :class="$store.darkMode.on && 'bg-gray-700'"
        class="block mt-4 text-xs bg-gray-200 px-4 py-2"
      >
        Toggle Dark Mode
      </button>
    </div>

    <footer x-data class="text-center mt-10">
      <p>Copyright &copy; <span x-text="new Date().getFullYear()"></span></p>
    </footer>

On gists

MatchResult component

Nette Nette-Controls PHP

MatchResultControl.php #

<?php


class MatchResult extends Control{

	const TEMPLATE_FULL = 'full';
	const TEMPLATE_INLINE = 'inline';

	public function renderFull($match){
		$this->render($match, self::TEMPLATE_FULL);
	}

	public function renderInline($match){
		$this->render($match, self::TEMPLATE_INLINE);
	}

	private function render($match, $templateName){
		$template = $this->createTemplate();
		$template->setFile(__DIR__.'/'.$templateName.'.latte');
		$template->match = $this->evaluateResult($match);
		$template->render();
	}

	private function evaluateResult($match){
		return //...
	}
}

On gists

CloneContent

Vue.js

CloneContent.vue #

<template>
  <slot />
</template>

<script>
export default {
  props: {
    target: {
      type: String
    }
  },
  mounted() {
    let target = document.querySelector(this.target)
    if (target) {
      let cloneContent = this.$slots.default()[0].el.cloneNode(true)
      target.replaceChildren(cloneContent)
    }
  }
}
</script>

<style lang="scss" scoped></style>

On gists

Google map (ES 6 / promise)

JavaScript ES 6 Vue.js

googlemap.js #

// Your personal API key.
// Get it here: https://console.cloud.google.com/google/maps-apis
const API_KEY = '***'
const CALLBACK_NAME = 'gmapsCallback'

let initialized = !!window.google
let resolveInitPromise
let rejectInitPromise
// This promise handles the initialization
// status of the google maps script.
const initPromise = new Promise((resolve, reject) => {
  resolveInitPromise = resolve
  rejectInitPromise = reject
})

export default function init() {
  // If Google Maps already is initialized
  // the `initPromise` should get resolved
  // eventually.
  if (initialized) return initPromise

  initialized = true
  // The callback function is called by
  // the Google Maps script if it is
  // successfully loaded.
  window[CALLBACK_NAME] = () => resolveInitPromise(window.google)

  // We inject a new script tag into
  // the `<head>` of our HTML to load
  // the Google Maps script.
  const script = document.createElement('script')
  script.async = true
  script.defer = true
  script.src = `https://maps.googleapis.com/maps/api/js?key=${API_KEY}&callback=${CALLBACK_NAME}`
  script.onerror = rejectInitPromise
  document.querySelector('head').appendChild(script)

  return initPromise
}

On gists

Accordion

Vue.js

Accordion.vue #

<template>
  <ul>
    <slot></slot>
  </ul>
</template>

<script>
export default {
  props: {},
  data() {
    return {
      AccordionState: {
        count: 0,
        active: 1
      }
    }
  },
  provide() {
    return { AccordionState: this.AccordionState }
  }
}
</script>

<style lang="scss" scoped></style>

On gists

Debounce, Throttle, Wait (ES6 Utils)

JS oneliners

fns.js #

export function debounce(fn, wait){
    let timer;
   return function(...args){
     if(timer) {
        clearTimeout(timer); // clear any pre-existing timer
     }
     const context = this; // get the current context
     timer = setTimeout(()=>{
        fn.apply(context, args); // call the function if time expires
     }, wait);
   }
}


export function throttle(fn, wait){
    let throttled = false;
    return function(...args){
        if(!throttled){
            fn.apply(this,args);
            throttled = true;
            setTimeout(()=>{
                throttled = false;
            }, wait);
        }
    }
}


export function wait(waitTime, callback = () => {}) {
  return new Promise(resolve => {
    setTimeout(() => {
      callback()
      resolve(true)
    }, waitTime)
  })
}



window.addEventListener('resize', debounce(() => {
    console.log('Resized!');
}, 200));


window.addEventListener('scroll', throttle(() => {
    console.log('Scrolled!');
}, 200));