Jak v jQuery vytvořit jednoduchý doplněk

Dělám doplněk který zobrazuje Google mapu. Doplněk umožňuje zobrazit několik markerů na mapě, nebo zobrazit 1 marker kterým je možné uživatelsky vybrat pozici. Nyní bych potřeboval rozšířit tento doplněk o možnost zadání souřadnic markeru z venku doplňku.

Jak to nyní funguje

<div id="google-map">v tomto divu je zobrazena mapa na které je marker</div>

Úkolem je této mapě (map může být na stránce více) nastavit souřadnice markeru.

Vyřešení

Do JavaScriptu pro zobrazení mapy přidám následující kód:

$( document ).ready( function() {

  $.fn.setMarkerPosition = function(lon, lat){
    $(this).css("border", "pink solid 10px");//at je to videt :-)
    alert("lon: " + lon + ", lat: " + lat );
    return this;
  };
  //...

Nyní stačí zavolat námi vytvořenou funkci setMarkerPosition()

$( "div#nette-g-map-canvas" ).setMarkerPosition( 1.1111, 2.2222 );

 

Google Analytics: Změna URL

Dost často se setkávám se stránkami které mají veškerý svůj obsah na jedné dlouhé stránce. Stránka je rozdělena na sekce a při zobrazení sekce se změní URL adresa (většinou se změní hashtag: #kontakt, #nabidka, #kontaktni-formular, … )

Pokud na tokovou stránku nasadíte Google Analytics, měření nebude dávat smysl (uvidíte statistiky pouze pro jednu stránku). Nebudete vědět jaké sekce uživatele zajímají, na jaké sekce přicházejí, z jakých sekcí odcházejí,….

Tento problém jsem vyřešil zajímavým způsobem. Pokud dojde ke změně URL (změní se hashtag), pošlu do Google Analytics zprávu o tom kde se nachází uživatel:

var page = location.pathname + "#"+ hashtag;
ga( 'send', 'pageview', page );

Kde location.pathname je cesta aktuální URL.

 

Breadcrumbs – drobečková navigace

Co je to breadcrumbs?

Breadcrumbs neboli drobečková navigace je sada odkazů které mohou uživateli pomoci pochopit a procházet hierarchii stránek. Příklad:

Webmaster ToolsHelp articlesMy site and GoogleCreating Google-friendly sites

Přidáte-li breaderumbs navigaci na Vaše stránky pomůžete vyhledávačům pochopit navigaci na stránkách a vyhledávače tuto informaci začnou prezentovat při vyhledávání:

breadcrumbs

 Ukázka použití

<div itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <a href="http://www.example.com/knihy" itemprop="url">
    <span itemprop="title">Knihy</span>
  </a> ›
  <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
    <a href="http://www.example.com/knihy/autori" itemprop="url">
      <span itemprop="title">Autoři</span>
    </a> ›
    <div itemprop="child" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
      <a href="http://www.example.com/knihy/autori/bozena-nemcova" itemprop="url">
        <span itemprop="title">Božena Němcona</span>
      </a>
    </div>
  </div>
</div>

 Ověření správné funkčnosti

Správnost konfigurace drobečkové navigace můžete ověřit na adrese: https://developers.google.com/structured-data/testing-tool/

Grunt: Warning: stdout maxBuffer exceeded. Use –force to continue.

Pokud váš grunt sckript vypisuje hodně údajů na obrazovku, snadno se stane že dojte k přetečení defaultního bufferu. Skript se nedokončí a zkončí hláškou:

Warning: stdout maxBuffer exceeded. Use --force to continue.

Aborted due to warnings.

Doporučuji deaktivovat maxBuffer:

shell: {
    yourCommand: {
        command: [
            'command to execute'
        ],
        options: {
            execOptions: {
                maxBuffer: Infinity
            }
        }
    }
}

 

Nette – validace formuláře – zadejte jméno nebo nick

Při práci s formuláři dost často potřebujete aby byl vyplněn jeden z důležitých údajů. V mém případě uživatel musí zadat svoje jméno nebo nick. Může zadat jméno a zároveň nick, nesmí se však stát že nezadá ani jméno ani nick:

        $form = new Form;
        $form->addText('name', 'Jméno:');
        $form->addText('nick', 'Nick:');
        
        $form->addSubmit('submit', 'Odeslat');

Pro vytvoření podmínky na jiný prvek použijeme addConditionOn. Prvním parametrem je prvek na který se odvoláváme a druhým parametrem je validační pravidlo.

        $form = new Form;
        $form->addText('name', 'Jméno:');
        $form->addText('nick', 'Nick:')
            ->addConditionOn($form['name'], ~Form::FILLED)
                ->setRequired('Zadejte prosím Vaše jméno nebo nick');

        $form->addSubmit('submit', 'Odeslat');

 

První aplikace pro Pebble hodinky

Tvorba aplikací pro Pebble hodinky je velice jednoduchá. Celou aplikaci dokážete vytvořit v cloudovém IDE. Nepotřebujete ani Pebble hodinky.

Vytvořenou aplikaci můžete spustit na emulátoru (je součástí cloud IDE) nebo fyzicky na hodinkách (pokud je máte).

Vytvoření aplikace v CloudPebble

Zaregistrujte se na https://cloudpebble.net/

Vytvořte nový projekt: PROJECTS -> CREATE

  • Project name: zadejte název vašeho projektu (například Hello)
  • Project type: Pebble C SDK
  • SDK Version: SDK 2
  • Template: HelloWorld

Tlačítkem CREATE vytvoříme projekt.

Máme základ hotov. Zkompilujeme ho: COMPILATION -> RUN BUILD. Zvolíme EMULATOR a klikneme na INSTALL ON APLITE.

Spustí se emulátor a můžeme vylepšovat.

Vytvoření nové textové vrstvy

text_layer = text_layer_create(GRect(0, 0, 144, 154));

Každá vrstva je vymezena hranicemi. Hranice určíme funkcí Grect.

Funkce Grect má následující parametry: Grect( x, y, size_x, size_y )

Průhledný PNG obrázek

Hodně jsem zápasil s vložením průhledného obrázku. Obrázek byl černý a měl průhledná místa. Řešení:

g_bitmap_layer_weather = bitmap_layer_create(GRect((bounds.size.w-25), (bounds.size.h-25), 25, 25));
bitmap_layer_set_bitmap(g_bitmap_layer_weather, gbitmap_create_with_resource(RESOURCE_ID_WATHERSUNNY_BLACK));  
bitmap_layer_set_compositing_mode(g_bitmap_layer_weather, GCompOpClear);

 

 

Tahák pro Composer

Jak stáhnout balíček do nové složky s projektem?

composer create-project nette/sandbox nazev-slozky-s-projektem

Kde složka nazev-slozky-s-projektem bude automaticky vytvořena

Jak zobrazit verze nainstalovaných balíčků?

composer show -i

composer install

Tím to příkazem nainstalujeme všechny balíčky ze souboru composer.json. Zároveň dojde k vytvoření souboru composer.lock který obsahuje seznam nainstalovaných verzí.

Pokud se dostanete k projektu ve kterém existuje composer.lock použijte pro stažení balíčků příkaz: composer install

composer update

Vynucení aktualizace balíčků. Tento příkaz přegeneruje soubor composer.lock.

Odinstalování balíčku

composer remove nette/nazev-balicku

Instalace konkrétní verze balíčku

Při instalaci se konkrétní verze píše za dvojtečku za název balíčku:

composer require facebook/php-sdk-v4:4.0.*
composer require google/apiclient:~1.0
composer require kertz/twitteroauth:dev-master
composer require venca-x/social-login:dev-master
composer require venca-x/nette.ajax.js:dev-master#fe640f40c9606e78f4fd31471931969c65b175c0

Instalace balíčků pro vývoj

ne vždy jsou balíčky nutnou součástí projektu (tester, phpstan, …). Tyto balíčky nainstalujeme s parametrem –dev

composer require --dev phpstan/phpstan-nette
Name Ukázka Popis
Přesná verze 1.0.2 Můžete určit přesnou verzi balíčku.
Rozsah >=1.0
>=1.0 <2.0
>=1.0 <1.1 || >=1.2
Operátory můžete určit rozsah platných verzí. Operátory jsou: >, >=, <, <=, !=
Můžete definovat více rozsahů. Rozsahy oddělené mezerou, nebo čárkou, budou považovány za logický AND.Dvojitá trubka (||), je považována za logický OR.
Hyphen Range 1.0 - 2.0 Například 1.0-2.0 odpovídá >= 1.0.0 <2.1
1.0.0 – 2.1.0 odpovídá >= 1.0.0 <= 2.1.0
Maska 1.0.* * je zástupný znak.  1.0.* Je ekvivalent >= 1.0 <1.1
Tilda operátor ~1.2 ~1.2 odpovídá >= 1.2 <2.0
Tilda operátor ~1.2.3 ~1.2.3 odpovídá >= 1.2.3 <1.3.0
Stříška operátor ^0.3 ^0.3 odpovídá >= 0.3 <0.4
Stříška operátor ^1.2.3 ^1.2.3 odpovídá >= 1.2.3 <2.0

U vlnovky záleží na tom, kolik číslic je uvedeno v čísle verze – poslední uvedená číslice se může lišit.

  • Preferujte operátor stříšky – je to nejjednodušší způsob, jak vynutit minimální verze oprav.

Jak v Nette vytvořit PDF fakturu

Pokud budete v Nette potřebovat vytvořit fakturu, doporučuji plugin Eciovni.

composer require OndrejBrejla/Eciovni ~1.1

Následně stačí jen vytvořit akci a funkci pro zobrazení faktury:

use OndrejBrejla\Eciovni\Eciovni;
use OndrejBrejla\Eciovni\ParticipantBuilder;
use OndrejBrejla\Eciovni\ItemImpl;
use OndrejBrejla\Eciovni\DataBuilder;
use OndrejBrejla\Eciovni\TaxImpl;

//...


    public function actionDefault() {
        // in case you downloaded mPDF separately
        // include_once(LIBS_DIR . '/MPDF54/mpdf.php');
        $mpdf = new \mPDF('utf-8');

        // Exporting prepared invoice to PDF.
        // To save the invoice into a file just use the second and the third parameter, equally as it's described in the documentation of mPDF->Output().
        $this['eciovni']->exportToPdf( $mpdf );
        //file_put_contents( "faktura.pdf", $this['eciovni']->exportToPdf( $mpdf ) );//uloz pdf na disk
    }

//..


    protected function createComponentEciovni() {
        $dateNow = new \DateTime();
        $dateExp = new \DateTime();
        $dateExp->modify('+14 days');
        $variableSymbol = '1234';

        $supplierBuilder = new ParticipantBuilder('Jan Baťa', 'Vodňany', '11', 'Čurákov', '13000');
        $supplier = $supplierBuilder->setIn('12345678')->setTin('CZ12345678')->setAccountNumber('123456789 / 1111')->build();
        $customerBuilder = new ParticipantBuilder('ěščřžýáíé ŠČŘŽÝÁÍÉ', 'Another street', '3', 'Prague 9', '19000');
        $customer = $customerBuilder->setAccountNumber('123456789 / 1111')->build();

        $items = array(
            new ItemImpl('Tworba webu', 1, 900, TaxImpl::fromPercent(22)),
            new ItemImpl('Správa databáze', 1, 900, TaxImpl::fromLowerDecimal(0.22)),
            new ItemImpl('Píčoviny', 1, 900, TaxImpl::fromUpperDecimal(1.22)),
        );
		/*
		for($i = 0; $i < 100; $i++)
		{
			$items[] = new ItemImpl( "Tworba webu " . $i, 1, 900, TaxImpl::fromPercent(22));
		}*/

        $dataBuilder = new DataBuilder(date('YmdHis'), 'Faktura - faktura číslo', $supplier, $customer, $dateExp, $dateNow, $items);
        $dataBuilder->setVariableSymbol($variableSymbol)->setDateOfVatRevenueRecognition($dateNow);
        $data = $dataBuilder->build();

        return new Eciovni($data);
    }

 

Grunt + Bower: Ajax v Nette

Mám projekt v Nette ve kterém potřebuji rozjet Ajax. Na projektu mám již připraven Grunt (jak nainstalovat Grunt) a Bower (slibuji to dlouho ale o tom zase někdy příště).

Pro Ajax v Nette doporučuji nette.ajax.js (od Vojtěcha Dobeše). Nette.ajax.js samozřejmě nainstalujeme přes Bower:

bower install nette.ajax.js --save-dev

Pro automatizaci používám Grunt (jak nainstalovat Grunt), do kterého existuje nepřeberné množství doplňků.

Pro spojení více .js souborů do jednoho používám doplněk grunt-contrib-concat kde mám vytvořený následující task:

        concat: {
            js: {
                src: ['bower_components/jquery/dist/jquery.min.js',
                    'bower_components/nette.ajax.js/nette.ajax.js',
                    'vendor/nette/forms/src/assets/netteForms.js',
                    'www/js/main.js'],
                dest: 'www/js/compiled.js',
                nonull: true
            }
        },

V souboru compiled.js máme potřebné js soubory. Můžeme se pustit do další fáze.

Nette + Ajax

Ajaxace již funkčních částí je v Nette velice jednoduchá. Nyní mám vytvořený formulář který odesílá data. Po odeslání formuláře se znovu načte kompletně celá stránka. Tento skript vylepšíme, aby se po odeslání formuláře nemusela načítat komplet celá stránka ale pouze odeslaný formulář (u mne to je formulář s rezervací).

Pojďme si připravit inicializace knihovny nette.ajax.js do souboru main.js:

$(function () {
    $.nette.init();// And you fly... 
});

Mému formuláři stačí přidat class ajax:

$form = new Form;
$form->getElementPrototype()->class( 'ajax' );

V presenteru nyní máme funkci isAjax, která nám vrací TRUE pokud se jedná o Ajaxový požadavek.

Po odeslání formuláře se přesvědčíme zda byl odeslán Ajaxem:

    public function selectWorkshopFormSucceeded( $form, $values )
    {
        if ($this->isAjax()) {
            echo "fomulář odeslán AJAXem";
        }
        else
        {
            echo "fomulář nebyl odeslán AJAXem";
        }
        exit();
    }

V latte můžeme jednotlivé bloky zabalit do snippetu a nechat překreslit pouze tento snippet:

{snippet workshop}
   {control selectWorkshopForm}
{/snippet}
    public function selectWorkshopFormSucceeded( $form, $values )
    {
        if ($this->isAjax()) {
            $this->redrawControl( 'workshop' );//znovu vykresli snippet workshop
        }
        else
        {
            $this->redirect( 'this' );//znovu vykresli celou stranku
        }
    }

Proto Nette miluju!