Odczyt atrybutów elementu w obsłudze zdarzena w javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<select name="banner_url" onchange="var idx=this.selectedIndex;
var value=this.options[idx].getAttribute('banner_url');
var element = document.getElementById('img_banner_url');
element.setAttribute('src', value); element.style.display='block'">


!{section name=ii loop=$data}!
    !{capture assign=banner_url}!http://kody.wig.pl/!{/capture}!
    <option value="!{$banner_url}!" banner_url="!{$banner_url}!">
    !{$data[ii].name}! ---> !{$banner_url}!</option>
!{/section}!

</select>
<br><br>

<img src="" id="img_banner_url" style="display:none">

Przykład uruchomienia smartów

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require_once('/app/config.php');
require_once('/app/smarty-3.1.29/libs/Smarty.class.php');

$smarty=new Smarty;
$smarty->template_dir = '/app/templates/';
$smarty->compile_dir = '/app/data/smarty/templates_c/';
$smarty->cache_dir = '/app/data/smarty/cache/';
$smarty->config_dir = '/app/data/smarty/config/';
$smarty->caching= false;
$smarty->force_compile=true;
//$smarty->force_compile=false;
$smarty->configLoad('pl.conf', 'index');
$smarty->left_delimiter = '!{';
$smarty->right_delimiter = '}!';

$data_to_send=$smarty->fetch('index.html');

header("Connection: close");
ignore_user_abort(true);
header('Content-type: text/html; charset='.$config['encoding']);
header("Content-Length: ".mb_strlen($data_to_send, $config['encoding']));

echo $data_to_send;

Template strings w Javascript ES6, ES2015

Ile razy człowiek się męczył aby zwykły formularz ze zmiennymi zapisać w js 😉
Z pokonaniem tego problemu sięgamy po template string. Używamy tego znaku (`) znajduje się on nad tabulatorem z angielskiego backtick, po naszemu odwrócony apostrof a zmienne umieszczamy w takiej formie ${zmienna}
Wszystko razem można zapisać `${zmienna}`

A teraz małe przykłady.

Powiedzmy że mamy sobie obiekt.

1
2
3
4
5
var person = {
    name: 'Greg',
    job: 'front-end',
    city: 'Warszawa'
}

A html to:

1
2
3
4
5
var html =
'<div class="person">'+
    '<h1>' + person.name + '</h1>' +
    '<h2>' + person.job + ' ' + person.city + '</h2>' +
'</div>';

A nie prościej tak?:

1
2
3
4
5
6
const html = `
    <div class="person">
        <h1>${person.name}</h1>
        <h2>${person.job} ${person.city}</h2>
    </div>
`;

Oczywiście można te zmienne mnożyć, dodawać odejmować itd. 🙂

1
2
3
4
5
const x = 1;
const y = 2;
const result = `${ x + y }`;

console.log(result); // 1 + 2 = 3

Taki zapis jak pokazałem niesamowicie skraca nam pracę i mniej błędów popełniamy, ale jest jeden problem i to poważny a zwie się on IE (Internet Explorer) 🙂
Niestety nasz kod musi być jeszcze przez jakiś czas wstecz kompatybilny ze starymi przeglądarkami, dlatego w swojej pracy używam gulp, webpacka a czasami je również łączę.

Małe wytłumaczenie:
1. Gulp to, oparty o platformę Node.js, system do automatyzacji pracy. Głównym jego zadaniem jest więc zautomatyzowanie wielu czynności, jakie musi wykonać programista podczas swojej pracy. Przykład użycia – zerknij tutaj
2. Webpack to narzędzie, które rozwiązuje problem dzielenia kodu na moduły i pozwala łatwo zarządzać zależnościami występującymi między nimi.

Więcej poszukajcie sobie w google bo naprawdę warto znać te technologie.

Wracając do naszego problemu z IE i nie tylko, ja użyłem biblioteki gulp-bable
Najpierw instalacja z linii komend biblioteki gulp-babel

1
npm install --save-dev gulp-babel babel-core babel-preset-es2015

Teraz dodajemy do gulpfile.js naszą bibliotekę oraz task

1
2
3
4
5
6
7
8
9
10
11
const gulp = require('gulp');
const babel = require('gulp-babel');


gulp.task('js', function () {
    return gulp.src('src/**/*.js')
        .pipe(babel({
            "presets": ["es2015"]
        }))
        .pipe(gulp.dest('dist'));
});

Taki kod w pliku template.js który chcemy zmienić na es2015 umieszczamy w folderze src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const person = {
    name: 'Greg',
    job: 'front-end',
    city: 'Warszawa'
}

const html = `
    <div class="person">
        <h1>${person.name}</h1>
        <h2>${person.job} ${person.city}</h2>
    </div>
`;

console.log(html);

const x = 1;
const y = 2;
const result = `${ x + y }`;

console.log(result);

Po uruchomieniu taska js w folderze dist otrzymujemy js zmieniony na es205, wynik poniżej

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'use strict';

var person = {
    name: 'Greg',
    job: 'front-end',
    city: 'Warszawa'
};

var html = '\n    <div class="person">\n        <h1>' + person.name + '</h1>\n        <h2>' + person.job + ' ' + person.city + '</h2>\n    </div>\n';

console.log(html);

var x = 1;
var y = 2;
var result = '' + (x + y);

console.log(result);

I ten kod załączamy do naszej strony będzie działać również ze starszymi przeglądarkami.

Oczywiście to tylko pobieżne poruszenie tego tematu, więcej w google 😉

Pasek postępu przewijania strony.

Dobrych praktyk UX nigdy za wiele. Warto czasami do strony dodać coś co nawet w najmniejszym stopniu zwiększy czas przebywania usera na stronie.

Najpierw pobieramy o ile przewinęliśmy stronę od lewego górnego rogu window.pageYOffset,
później pobieramy wysokość okna bez uwzględniania toolbarów i scrollbarów window.innerHeight, następnie pobieramy document.body.clientHeight czyli wysokość całego okna.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const ProgressBar = function () {

    window.addEventListener('scroll', () => {
        let ws = window.pageYOffset,
            wh = window.innerHeight,
            dh = document.body.clientHeight;
        let scrollPercent = (ws / (dh-wh)) * 100;
        const progressBar = document.querySelector('#progress');
        if(ws > 50) {
            progressBar.setAttribute('style','width:'+ scrollPercent + '%');
        } else {
            progressBar.removeAttribute('style');
        }
    });

}();

Jeżeli przewiniemy o więcej niż 50px wtedy do id progress dodajemy style width, jeżeli jest mniejsze to usuwamy atrybut style z id.

Dodajemy też css aby to zadziałało.

1
2
3
4
5
6
7
.bar {
    position: fixed;
    background: rgb(255, 0, 0);
    height: 10px;
    width: 0;
    top: 0;
}

Działający przykład można znaleźć tutaj – działający przykład

Ustawianie paddingu czcionki w edytorze w NetBeans

Ustawianie paddingu czcionki w edytorze w NetBeans

W pliku:
C:\Users\Wojtek\AppData\Roaming\NetBeans\8.2\config\
Editors\Preferences\org-netbeans-modules-editor-settings-CustomPreferences.xml

należy dodać następujący kod xml:

1
2
3
<entry javaType="java.lang.Float" name="line-height-correction" xml:space="preserve">
<value><![CDATA[0.9]]></value>
</entry>

Rozwijane menu

Najpierw budujemy strukturę html. Wszystko jest robione w scss, js w wersji ES6 i gulp
Do ES6 używam gulp-babel aby przekonwertować js do es2015

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="container">

    <div id="accorions">
        <div class="accordion">Section 1</div>
        <div class="panel">
            <p>Sauerkraut can be garnished with cored avocado, also try decorateing the cake with hollandaise sauce.
                Asparagus can be marinateed with crushed lettuce, also try flavoring the loaf with salsa verde.
                with lobsters drink cream.</p>
        </div>

        <div class="accordion">Section 2</div>
        <div class="panel">
            <p>Aww, raid me parrot, ye dead landlubber! Swashbuckling, coal-black whales cowardly vandalize a mighty, gutless scabbard.
                Scabbards sing on booty at port degas! Small, dead tobaccos darkly fight a black, lively dagger.
                seashells fall with love.</p>
        </div>

        <div class="accordion">Section 3</div>
        <div class="panel">
            <p>Turbulence at the bridge was the adventure of mineral, lowered to a gravimetric mermaid.
                Moon at the universe was the mystery of coordinates, feeded to a real planet.
                wisely handle a processor.</p>
        </div>
    </div>

</div>

Dodajemy trochę css, na początku importuję normalize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@import "normalize";

.container {
    max-width: 500px;
    margin: 200px auto;

}

.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
    transition: 0.4s;
    &:after {
        content: '\002B';
        color: #777;
        font-weight: bold;
        float: left;
        margin-right: 5px;
    }
    &:hover {
        background-color: #ddd;
    }
    &.active {
        background-color: #ddd;
        &:after {
            content: "\2212";
        }
    }
}

.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
    li {
        list-style: none;
    }
}

Teraz najważniejsza część, dodajemy js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"use strict";

class Accordion {

    constructor(options) {
        this.options = options;
        this.type = options.type;
    }

    creatAccordion() {
        let that = this;
        let acc = this.getAccordionName();
        let i;

        for (i = 0; i < acc.length; i++) {
            acc[i].onclick = function() {
                if(options.type === true && !this.classList.contains(options.activeName)) {
                    that.removeActiveAndPanelHeight();
                }
                this.classList.toggle(options.activeName);
                let panel = this.nextElementSibling;
                if (panel.style.maxHeight){
                    panel.style.maxHeight = null;
                } else {
                    panel.style.maxHeight = panel.scrollHeight + "px";
                }
            }
        }
    }

    getAccordionName() {
        return document.getElementsByClassName(options.accordionName);
    }

    removeActiveAndPanelHeight() {
        const currentActive = document.querySelectorAll("."+ options.activeName);
        const heightPanel = document.querySelectorAll("." + options.panelName);

        Array.prototype.forEach.call(currentActive, function (el) {
            el.classList.remove(options.activeName);
        });

        Array.prototype.forEach.call(heightPanel, function (el) {
            el.removeAttribute("style");
        });
    }
}

const options = {
    'accordionName': 'accordion',
    'activeName': 'active',
    'panelName': 'panel',
    'type': true
};

const accordion = new Accordion(options);
accordion.creatAccordion();

Przykład można zobaczyć pod tym adresem

Ostatni parametr w options czyli ‚type’: true lub false umożliwia sterowaniem zwijania menu, true powoduje że każde kliknięcie na menu zwija inne rozwinięte zaś false pozostawia rozwinięte każde kliknięcie.
Oczywiście options można przenieść do html aby z tego miejsca sterować nie musi być ten obiekt umieszczony w js.

Całość włącznie z gulpem można zobaczyć na github