From ee5cda5e519c680343193ef3ed80c2c4af5246e9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 29 May 2019 21:23:46 -0300 Subject: [PATCH 01/23] Ajustes no menu --- templates/base.html.twig | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/templates/base.html.twig b/templates/base.html.twig index f623c9b..9a477d0 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -77,28 +77,36 @@ + + + - - - From e78b8d77a58c1f8b01c24cedcabc0dd398a9cb75 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 May 2019 22:42:47 -0300 Subject: [PATCH 02/23] cadastro de clientes --- .env | 2 +- config/packages/twig.yaml | 1 + data/database.sqlite | Bin 12288 -> 12288 bytes src/Controller/ImobiliariaController.php | 4 +- src/Controller/UsuarioController.php | 40 ++++ src/Entity/Endereco.php | 18 +- src/Entity/Usuario.php | 130 ++++++------- src/Forms/EnderecoType.php | 73 ++++++++ src/Forms/UsuarioType.php | 66 +++++++ templates/base.html.twig | 225 ++++++++++++----------- templates/footer.html.twig | 40 ++++ templates/usuario_cadastro.html.twig | 31 ++++ 12 files changed, 433 insertions(+), 197 deletions(-) create mode 100644 src/Controller/UsuarioController.php create mode 100755 src/Forms/EnderecoType.php create mode 100755 src/Forms/UsuarioType.php create mode 100755 templates/footer.html.twig create mode 100644 templates/usuario_cadastro.html.twig diff --git a/.env b/.env index 764f2c0..de47c35 100755 --- a/.env +++ b/.env @@ -24,7 +24,7 @@ APP_SECRET=db57d5b20b55689a1519cd62120fe723 # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url # For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db" # Configure your db driver and server_version in config/packages/doctrine.yaml -DATABASE_URL=sqlite:///%kernel.project_dir%/var/data.db/database.sqlite +DATABASE_URL=sqlite:///%kernel.project_dir%/data/database.sqlite ###< doctrine/doctrine-bundle ### ###> symfony/swiftmailer-bundle ### diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index d1582a2..16fdd4b 100755 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -2,3 +2,4 @@ twig: default_path: '%kernel.project_dir%/templates' debug: '%kernel.debug%' strict_variables: '%kernel.debug%' + form_themes: ['bootstrap_4_layout.html.twig'] diff --git a/data/database.sqlite b/data/database.sqlite index 176e6e0aa5a63d553b4b15d86c7b7b9792d6b036..b8b1444c5ab91b896a89380f1a790f54cf425188 100644 GIT binary patch delta 377 zcmZojXh@hK&B!)U##xY!K~H7_F9QPu6VF}-zC512n*{}Yc{cCmaTn%c;XBO0zn(va zpOfz}PcqP8#tgCs*%eqz2M6c`y8TIw2@>KYj%SQ)7~nfVUsxrv!M zddc~@xrxPz#VJ4($jrl_tg5JJ2sA~U0W1WO0m>C8rWAuk;KrE1ScWF`<*9|Kh2^Q` z2tz?yz-BV>Fo-Jy&6EeZ3~aLj&?y#1W(Fn(<}f1+EMY7oV@$Jv4ooi1$;``#IMbgI VVWcS7Nc(&&W+M9-pP7k?i2zj$X2$>k delta 44 zcmZojXh@hK&B!!S##xYwK~E!-mw|zSiDxeZUmnli&4L2HJe&9OxC?J)5%|Lo0PL>| ABLDyZ diff --git a/src/Controller/ImobiliariaController.php b/src/Controller/ImobiliariaController.php index 9eb5722..5677e40 100644 --- a/src/Controller/ImobiliariaController.php +++ b/src/Controller/ImobiliariaController.php @@ -2,7 +2,7 @@ namespace App\Controller; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use Symfony\Component\Routing\Annotation\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; /** @@ -12,7 +12,7 @@ class ImobiliariaController extends AbstractController { /** - * @Route("index") + * @Route("index", name="index") */ public function index() { diff --git a/src/Controller/UsuarioController.php b/src/Controller/UsuarioController.php new file mode 100644 index 0000000..f47c14f --- /dev/null +++ b/src/Controller/UsuarioController.php @@ -0,0 +1,40 @@ +createForm(UsuarioType::class, $usuario); + $form->handleRequest($request); + + if ($form->isSubmitted()) { + $usuario = $form->getData(); + $em = $this->getDoctrine()->getManager(); + $em->persist($usuario); + $em->flush(); + + return $this->redirectToRoute('index'); + } + + return $this->render('usuario_cadastro.html.twig', [ + 'form' => $form->createView() + ]); + } +} diff --git a/src/Entity/Endereco.php b/src/Entity/Endereco.php index a7ce442..b5234a9 100644 --- a/src/Entity/Endereco.php +++ b/src/Entity/Endereco.php @@ -1,5 +1,7 @@ name; + return $this->nome; } /** - * @param mixed $name + * @param mixed $nome */ - public function setName($name): void + public function setNome($nome): void { - $this->name = $name; + $this->nome = $nome; } /** @@ -107,15 +105,15 @@ public function setName($name): void */ public function getCpfCnpj() { - return $this->cpf_cnpj; + return $this->cpfCnpj; } /** - * @param mixed $cpf_cnpj + * @param mixed $cpfCnpj */ - public function setCpfCnpj($cpf_cnpj): void + public function setCpfCnpj($cpfCnpj): void { - $this->cpf_cnpj = $cpf_cnpj; + $this->cpfCnpj = $cpfCnpj; } /** @@ -123,15 +121,15 @@ public function setCpfCnpj($cpf_cnpj): void */ public function getDtNascimento() { - return $this->dt_nascimento; + return $this->dtNascimento; } /** - * @param mixed $dt_nascimento + * @param mixed $dtNascimento */ - public function setDtNascimento($dt_nascimento): void + public function setDtNascimento($dtNascimento): void { - $this->dt_nascimento = $dt_nascimento; + $this->dtNascimento = $dtNascimento; } /** @@ -139,15 +137,15 @@ public function setDtNascimento($dt_nascimento): void */ public function getDtCadastro() { - return $this->dt_cadastro; + return $this->dtCadastro; } /** - * @param mixed $dt_cadastro + * @param mixed $dtCadastro */ - public function setDtCadastro($dt_cadastro): void + public function setDtCadastro($dtCadastro): void { - $this->dt_cadastro = $dt_cadastro; + $this->dtCadastro = $dtCadastro; } /** @@ -182,38 +180,6 @@ public function setSexo($sexo): void $this->sexo = $sexo; } - /** - * @return mixed - */ - public function getLogin() - { - return $this->login; - } - - /** - * @param mixed $login - */ - public function setLogin($login): void - { - $this->login = $login; - } - - /** - * @return mixed - */ - public function getSenha() - { - return $this->senha; - } - - /** - * @param mixed $senha - */ - public function setSenha($senha): void - { - $this->senha = $senha; - } - /** * @return mixed */ @@ -261,4 +227,20 @@ public function setContratoAdm($contratoAdm): void { $this->contratoAdm = $contratoAdm; } + + /** + * @return string + */ + public function getTipoUsuario(): ?string + { + return $this->tipoUsuario; + } + + /** + * @param string $tipoUsuario + */ + public function setTipoUsuario(string $tipoUsuario): void + { + $this->tipoUsuario = $tipoUsuario; + } } diff --git a/src/Forms/EnderecoType.php b/src/Forms/EnderecoType.php new file mode 100755 index 0000000..14cab63 --- /dev/null +++ b/src/Forms/EnderecoType.php @@ -0,0 +1,73 @@ +add('logradouro', TextType::class, [ + 'label' => 'Logradouro:' + ]) + ->add('bairro', TextType::class, [ + 'label' => 'Bairro:', + ]) + ->add('numero', TextType::class, [ + 'label' => 'Numero:', + ]) + ->add('cep', TextType::class, [ + 'label' => 'CEP:', + ]) + ->add('complemento', TextType::class, [ + 'label' => 'Complemento', + ]) + ->add('uf', TextType::class, [ + 'label' => 'UF:', + ]) + ->add('cidade', TextType::class, [ + 'label' => 'Cidade:', + ]) + ->add('ddd', TextType::class, [ + 'label' => 'DDD:', + ]) + ->add('telefone', TextType::class, [ + 'label' => 'Telefone:', + ]) + ->add('dddCelular', TextType::class, [ + 'label' => 'DDD Celular:', + ]) + ->add('celular', TextType::class, [ + 'label' => 'Celular:', + ]) + ; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Usuario::class, + ]); + } +} diff --git a/src/Forms/UsuarioType.php b/src/Forms/UsuarioType.php new file mode 100755 index 0000000..ffdefd1 --- /dev/null +++ b/src/Forms/UsuarioType.php @@ -0,0 +1,66 @@ +setAction('usuario') + ->setMethod('POST') + ->add('nome', TextType::class, [ + 'label' => 'Nome' + ]) + ->add('CpfCnpj', TextType::class, [ + 'label' => 'CpfCnpj', + ]) + ->add('sexo', TextType::class, [ + 'label' => 'Sexto', + ]) + ->add('email', EmailType::class, [ + 'label' => 'Email', + ]) + ->add('dtNascimento', DateType::class, [ + 'label' => 'Data de Nascimento', + 'widget' => 'single_text', + 'attr' => ['class' => 'js-datepicker'], + ]) + ->add('dtCadastro', DateType::class, [ + 'label' => 'Data de Cadastro', + 'widget' => 'single_text', + 'attr' => ['class' => 'js-datepicker'], + ]) + ->add('tipoUsuario', TextType::class, [ + 'label' => 'Tipo De usuário', + ]) + ; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Usuario::class, + ]); + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index 9a477d0..1996ec2 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -18,10 +18,10 @@ - Imobiliária App + Imobiliária - + @@ -29,136 +29,137 @@ - - - + - - + +
- - + + - + +
+{##} + From 1a70498f09e5b6262d013fe368d8632d25396b43 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 31 May 2019 20:43:01 -0300 Subject: [PATCH 05/23] dataFixtures --- composer.json | 1 + composer.lock | 127 +++++++++++++++++++- config/bundles.php | 1 + data/database.sqlite-journal | Bin 0 -> 8720 bytes src/DataFixtures/AppFixtures.php | 197 +++++++++++++++++++++++++++++++ symfony.lock | 15 +++ 6 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 data/database.sqlite-journal create mode 100644 src/DataFixtures/AppFixtures.php diff --git a/composer.json b/composer.json index ba92f0b..d94ecbe 100755 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "symfony/yaml": "4.2.*" }, "require-dev": { + "doctrine/doctrine-fixtures-bundle": "^3.1", "symfony/debug-pack": "*", "symfony/maker-bundle": "^1.0", "symfony/profiler-pack": "*", diff --git a/composer.lock b/composer.lock index 47e961c..5c2ef6d 100755 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cee4085fe3fa88057621162b3c43239f", + "content-hash": "c5f7fa86ada957082d10d9e8bc1b7adc", "packages": [ { "name": "doctrine/annotations", @@ -5466,6 +5466,129 @@ } ], "packages-dev": [ + { + "name": "doctrine/data-fixtures", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a", + "reference": "3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.2", + "php": "^7.1" + }, + "conflict": { + "doctrine/phpcr-odm": "<1.3.0" + }, + "require-dev": { + "doctrine/dbal": "^2.5.4", + "doctrine/orm": "^2.5.4", + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM with PHP 7", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database" + ], + "time": "2018-03-20T09:06:36+00:00" + }, + { + "name": "doctrine/doctrine-fixtures-bundle", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", + "reference": "f016565b251c2dfa32a8d6da44d1650dc9ec1498" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/f016565b251c2dfa32a8d6da44d1650dc9ec1498", + "reference": "f016565b251c2dfa32a8d6da44d1650dc9ec1498", + "shasum": "" + }, + "require": { + "doctrine/data-fixtures": "^1.3", + "doctrine/doctrine-bundle": "^1.6", + "php": "^7.1", + "symfony/doctrine-bridge": "~3.4|^4.1", + "symfony/framework-bundle": "^3.4|^4.1" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "phpunit/phpunit": "^7.4", + "symfony/phpunit-bridge": "^4.1" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\FixturesBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineFixturesBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "Fixture", + "persistence" + ], + "time": "2018-12-21T10:10:51+00:00" + }, { "name": "easycorp/easy-log-handler", "version": "v1.0.7", diff --git a/config/bundles.php b/config/bundles.php index c2a87a8..d0d2715 100755 --- a/config/bundles.php +++ b/config/bundles.php @@ -14,4 +14,5 @@ Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\Bundle\WebServerBundle\WebServerBundle::class => ['dev' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], ]; diff --git a/data/database.sqlite-journal b/data/database.sqlite-journal new file mode 100644 index 0000000000000000000000000000000000000000..7f5795a034ca5ea47ed623eb1aafb56603c49f52 GIT binary patch literal 8720 zcmeI&!HR-V6b9fk+9t3Zh=>^&28mWtT+OE1&7$SN(7w&3WHPi%NcdRodV$`kC+KM7 z+#qVzB8LAWc=Y1$@zd2sB0UbP-76oNLH{f^hu)gp*O_4yOaFzU`! z9Lq!|bKWMVMa`DuxSZ0U{M2cN=Mp(j@-u%ieo?u88mxnL8l*ZiyCRP?ENV14@;z%T zzp>y>hTezp#h^$KqoVS9ms#B3Y!ihmb?Wl_Nk`VNMxH)uls!QYc;ZU04)1F g<_C_hAOHafKmY;|fB*y_009U<00Q?C$o~I00&X^8TmS$7 literal 0 HcmV?d00001 diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php new file mode 100644 index 0000000..c5d6d13 --- /dev/null +++ b/src/DataFixtures/AppFixtures.php @@ -0,0 +1,197 @@ + 'PB', 'Campina Grande' => 'PB', 'Princesa Isabel' => 'PB', 'São Paulo' => 'SP', + 'Santa Inês' => 'MA', 'Caruarú' => 'PE', 'Recife' => 'PE', 'Natal' => 'RN', 'Tavares' => 'PB', 'Triunfo' => 'PE' + ]; + + public function load(ObjectManager $manager): void + { + $this->loadEmderecos($manager); +// $this->loadUsuarios($manager); + } + + + /** + * @param ObjectManager $manager + */ + private function loadEmderecos(ObjectManager $manager): void + { + for($i = 1; $i = 5; $i++) { + + $endereco = new Endereco(); + $endereco->setLogradouro(self::LOGRADOUROS[rand (0 , 10 )]); + $endereco->setBairro(self::BAIRROS[rand(0, 12)]); + $endereco->setNumero(rand(1, 2000)); + $endereco->setCep($this->cepRandom()); + + $cidade = self::CIDADES[rand(0, 9)]; + $uf = self::CIDADES_UF[$cidade]; + + $endereco->setCidade($cidade); + $endereco->setUf($uf); + + $manager->persist($endereco); + } + + $manager->flush(); + } + + private function loadUsuarios(ObjectManager $manager): void + { + $enderecos = $manager->getRepository(Endereco::class)->findAll(); + + foreach ($enderecos as $endereco) { + + $usuario = new Usuario(); + $usuario->setNome(self::NOMES[rand(0, 18)].' '.self::SOBRE_NOMES[rand(0, 15)]); + $usuario->setCpfCnpj($this->cpfRandom()); + $usuario->setEndereco($endereco); + $usuario->setDtNascimento($this->randomDateAniversario()); + $usuario->setDtCadastro($this->randomDateCadastro()); + } + + } + + private function loadImoveis(ObjectManager $manager) + { +// $enderecos = $manager->getRepository(Endereco::class)->findAll(); +// +// foreach ($enderecos as $endereco) { +// $imovel = new Imovel(); +// $imovel->setEndreco($endereco); +// $imovel->setDtCadastro($this->randomDateCadastro()); +// } + + } + + private function loadContratoAdm(ObjectManager $manager) + { + + } + + private function loadContratoLocacao(ObjectManager $manager) + { + + } + + /** + * @param DateTime $start + * @param DateTime $end + * @return DateTime + */ + private function randomDateAniversario() + { + $start = new \DateTime('01/01/1930'); + $end = new \DateTime('01/01/2005'); + $randomTimestamp = mt_rand($start->getTimestamp(), $end->getTimestamp()); + $randomDate = new DateTime(); + $randomDate->setTimestamp($randomTimestamp); + return $randomDate; + } + + /** + * @param DateTime $start + * @param DateTime $end + * @return DateTime + */ + private function randomDateCadastro() + { + $start = new \DateTime('01/01/2015'); + $end = new \DateTime('01/06/2019'); + $randomTimestamp = mt_rand($start->getTimestamp(), $end->getTimestamp()); + $randomDate = new DateTime(); + $randomDate->setTimestamp($randomTimestamp); + return $randomDate; + } + + /** + * @return string + */ + private function cepRandom() + { + return rand(1, 9).rand(0, 9).rand(0, 9).rand(0, 9).rand(0, 9).'-'.rand(0, 9).rand(0, 9).rand(0, 9); + } + + /** + * Método para gerar CPF válido, com máscara ou não + * @example cpfRandom(0) + * para retornar CPF sem máscar + * @param int $mascara + * @return string + */ + private function cpfRandom($mascara = "1"): string + { + $n1 = rand(0, 9); + $n2 = rand(0, 9); + $n3 = rand(0, 9); + $n4 = rand(0, 9); + $n5 = rand(0, 9); + $n6 = rand(0, 9); + $n7 = rand(0, 9); + $n8 = rand(0, 9); + $n9 = rand(0, 9); + $d1 = $n9 * 2 + $n8 * 3 + $n7 * 4 + $n6 * 5 + $n5 * 6 + $n4 * 7 + $n3 * 8 + $n2 * 9 + $n1 * 10; + $d1 = 11 - (self::mod($d1, 11) ); + if ($d1 >= 10) { + $d1 = 0; + } + $d2 = $d1 * 2 + $n9 * 3 + $n8 * 4 + $n7 * 5 + $n6 * 6 + $n5 * 7 + $n4 * 8 + $n3 * 9 + $n2 * 10 + $n1 * 11; + $d2 = 11 - (self::mod($d2, 11) ); + if ($d2 >= 10) { + $d2 = 0; + } + $retorno = ''; + if ($mascara == 1) { + $retorno = '' . $n1 . $n2 . $n3 . "." . $n4 . $n5 . $n6 . "." . $n7 . $n8 . $n9 . "-" . $d1 . $d2; + } else { + $retorno = '' . $n1 . $n2 . $n3 . $n4 . $n5 . $n6 . $n7 . $n8 . $n9 . $d1 . $d2; + } + return $retorno; + } + + /** + * @param $dividendo + * @param $divisor + * @return float + */ + private static function mod($dividendo, $divisor): float + { + return round($dividendo - (floor($dividendo / $divisor) * $divisor)); + } +} \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index 009f271..db9c3d7 100755 --- a/symfony.lock +++ b/symfony.lock @@ -20,6 +20,9 @@ "doctrine/common": { "version": "v2.10.0" }, + "doctrine/data-fixtures": { + "version": "v1.3.1" + }, "doctrine/dbal": { "version": "v2.9.2" }, @@ -41,6 +44,18 @@ "doctrine/doctrine-cache-bundle": { "version": "1.3.5" }, + "doctrine/doctrine-fixtures-bundle": { + "version": "3.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.0", + "ref": "fc52d86631a6dfd9fdf3381d0b7e3df2069e51b3" + }, + "files": [ + "src/DataFixtures/AppFixtures.php" + ] + }, "doctrine/doctrine-migrations-bundle": { "version": "1.2", "recipe": { From fd2528c52f95c11a9cf5fe37e3517ced933dc594 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 31 May 2019 21:52:07 -0300 Subject: [PATCH 06/23] cadastro de usuario --- data/database.sqlite | Bin 12288 -> 12288 bytes data/database.sqlite-journal | Bin 8720 -> 0 bytes public/imagens/benvindo.png | Bin 0 -> 32427 bytes src/Controller/ImobiliariaController.php | 2 +- src/Controller/LoginController.php | 16 +++++ src/Controller/UsuarioController.php | 4 +- src/Forms/UsuarioType.php | 2 +- templates/base.html.twig | 4 +- templates/imobiliaria.html.twig | 81 +++++++++++++++++++++-- templates/listar_usuarios.html.twig | 2 +- 10 files changed, 99 insertions(+), 12 deletions(-) delete mode 100644 data/database.sqlite-journal create mode 100644 public/imagens/benvindo.png create mode 100644 src/Controller/LoginController.php diff --git a/data/database.sqlite b/data/database.sqlite index b8b1444c5ab91b896a89380f1a790f54cf425188..c8526831470bd969d6c275176f571cb67b6c41c8 100644 GIT binary patch delta 86 zcmZojXh@hK&B#7c#+i|QW5N=7K32XG2LAQ@G5nl-hxtl23koFhar(0IFo-KFD(X(& lp|2^M3I-18xrv!Mddc~@xrxQer8${-`H4WV`LLcXBLMg*8N&bo delta 40 wcmZojXh@hK&B!)U#+i|AW5N=79u~gC4E*c)WB57w4sR9|*vz;2u%0a=0PXq^&28mWtT+OE1&7$SN(7w&3WHPi%NcdRodV$`kC+KM7 z+#qVzB8LAWc=Y1$@zd2sB0UbP-76oNLH{f^hu)gp*O_4yOaFzU`! z9Lq!|bKWMVMa`DuxSZ0U{M2cN=Mp(j@-u%ieo?u88mxnL8l*ZiyCRP?ENV14@;z%T zzp>y>hTezp#h^$KqoVS9ms#B3Y!ihmb?Wl_Nk`VNMxH)uls!QYc;ZU04)1F g<_C_hAOHafKmY;|fB*y_009U<00Q?C$o~I00&X^8TmS$7 diff --git a/public/imagens/benvindo.png b/public/imagens/benvindo.png new file mode 100644 index 0000000000000000000000000000000000000000..40fbabd4bc4daaab4d5c8583d2f7669183769cec GIT binary patch literal 32427 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 literal 0 HcmV?d00001 diff --git a/src/Controller/ImobiliariaController.php b/src/Controller/ImobiliariaController.php index 5677e40..6018cd0 100644 --- a/src/Controller/ImobiliariaController.php +++ b/src/Controller/ImobiliariaController.php @@ -12,7 +12,7 @@ class ImobiliariaController extends AbstractController { /** - * @Route("index", name="index") + * @Route("/", name="index") */ public function index() { diff --git a/src/Controller/LoginController.php b/src/Controller/LoginController.php new file mode 100644 index 0000000..f05d9f1 --- /dev/null +++ b/src/Controller/LoginController.php @@ -0,0 +1,16 @@ +render(); + } + +} \ No newline at end of file diff --git a/src/Controller/UsuarioController.php b/src/Controller/UsuarioController.php index d3146fd..c4a57dc 100644 --- a/src/Controller/UsuarioController.php +++ b/src/Controller/UsuarioController.php @@ -39,7 +39,7 @@ public function novoUsuario(Request $request) } /** - * @Route("/listar-usuarios", name="listar-usuarios") + * @Route("/listar", name="listar_usuarios") */ public function listarUsuarios(Request $request) { @@ -52,7 +52,7 @@ public function listarUsuarios(Request $request) } /** - * @Route("/editar-usuario/{id}", name="editar-usuario") + * @Route("/editar/{id}", name="editar_usuario") */ public function editarUsuario(int $id) { diff --git a/src/Forms/UsuarioType.php b/src/Forms/UsuarioType.php index ffdefd1..ba01612 100755 --- a/src/Forms/UsuarioType.php +++ b/src/Forms/UsuarioType.php @@ -24,7 +24,7 @@ class UsuarioType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->setAction('usuario') + ->setAction('../usuario') ->setMethod('POST') ->add('nome', TextType::class, [ 'label' => 'Nome' diff --git a/templates/base.html.twig b/templates/base.html.twig index 2ddd048..884ced9 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -25,7 +25,7 @@ - + @@ -81,7 +81,7 @@
diff --git a/templates/imobiliaria.html.twig b/templates/imobiliaria.html.twig index e0fdaaa..4de4a34 100644 --- a/templates/imobiliaria.html.twig +++ b/templates/imobiliaria.html.twig @@ -1,14 +1,85 @@ -{% include "base.html.twig" %} + + + + + + + + -
-

Bem vindos

-
- + Bem Vindo!! + + + + + + + + + + + + +
+
+

Cards

+
+ +
+
+
+
+
+
Casas para alugar a partir
+
R$150,000
+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
Aluguel por Temporada
+
R$2500,00
+
+
+ +
+
+
+
+
+
+ + +
+ + + + + + + + + diff --git a/templates/listar_usuarios.html.twig b/templates/listar_usuarios.html.twig index da47989..3cc3aa8 100644 --- a/templates/listar_usuarios.html.twig +++ b/templates/listar_usuarios.html.twig @@ -41,7 +41,7 @@ {{ usuario.email }} {{ usuario.sexo }} {{ usuario.dtCadastro|date("m/d/Y") }} - + From 2b508073aa936a03421617a44fa98c2c3090be7b Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 1 Jun 2019 15:11:48 -0300 Subject: [PATCH 07/23] cadastro de usuario --- data/database.sqlite | Bin 12288 -> 12288 bytes src/Controller/UsuarioController.php | 13 ++++++++++++- src/Entity/Endereco.php | 16 ++++++++-------- src/Entity/Usuario.php | 4 ++-- src/Forms/EnderecoType.php | 5 +++-- src/Forms/UsuarioType.php | 5 +++-- templates/base.html.twig | 4 ++-- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/data/database.sqlite b/data/database.sqlite index c8526831470bd969d6c275176f571cb67b6c41c8..bc2a424733342d88f5b69c11bedae4bd14475d9d 100644 GIT binary patch delta 619 zcmZojXh@hK&B!-V#+i|CW5N=CK32Ym4E*Q$XY&W}%ke$jEGTfEuil!KmqA=yQc_YF z3=EBo4UG^4kb@5yu<$ZK^Z`jpLHvqAvc{gwybPkEqS7E6fxx&Pss}7-3q(OQZ1O*eVQ8d97BQbdS*E4YP zJZ9i|%pb$g$#>$N){HC+3=Dx23w;3~IE!Kc delta 76 zcmZojXh@hK&B#7c#+i|QW5N=CCI*4ciUJ4tHa1u>3h^>9FtGBKFz~PEkKyO!JIq%C fluP2q$m!3>!yvA#sAxF3R!?*Cc3pV@-gpv@ diff --git a/src/Controller/UsuarioController.php b/src/Controller/UsuarioController.php index c4a57dc..c2040be 100644 --- a/src/Controller/UsuarioController.php +++ b/src/Controller/UsuarioController.php @@ -54,13 +54,24 @@ public function listarUsuarios(Request $request) /** * @Route("/editar/{id}", name="editar_usuario") */ - public function editarUsuario(int $id) + public function editarUsuario(int $id, Request $request) { $em = $this->getDoctrine()->getManager(); $usuario = $em->getRepository(Usuario::class)->find($id); $form = $this->createForm(UsuarioType::class, $usuario); + $form->handleRequest($request); + + if ($form->isSubmitted()) { + $usuario = $form->getData(); + $em = $this->getDoctrine()->getManager(); + $em->merge($usuario); + $em->flush(); + + return $this->redirectToRoute('listar_usuarios'); + } + return $this->render('usuario_cadastro.html.twig', [ 'form' => $form->createView() ]); diff --git a/src/Entity/Endereco.php b/src/Entity/Endereco.php index b5234a9..05279ae 100644 --- a/src/Entity/Endereco.php +++ b/src/Entity/Endereco.php @@ -17,7 +17,7 @@ class Endereco private $id; /** - * @ORM\Column(type="string", length=255, nullable=true) + * @ORM\Column(type="string", name="logradouro", length=255, nullable=true) */ private $logradouro; @@ -57,9 +57,9 @@ class Endereco private $telefone; /** - * @ORM\Column(type="integer", length=2, nullable=true) + * @ORM\Column(type="integer", name="ddd_telefone", length=2, nullable=true) */ - private $ddd; + private $dddTelefone; /** * @ORM\Column(type="integer", name="celular", length=9, nullable=true) @@ -228,17 +228,17 @@ public function setTelefone($telefone): void /** * @return mixed */ - public function getDdd() + public function getDddTelefone() { - return $this->ddd; + return $this->dddTelefone; } /** - * @param mixed $ddd + * @param mixed $dddTelefone */ - public function setDdd($ddd): void + public function setDddTelefone($dddTelefone): void { - $this->ddd = $ddd; + $this->dddTelefone = $dddTelefone; } /** diff --git a/src/Entity/Usuario.php b/src/Entity/Usuario.php index 85b2ba3..692db37 100644 --- a/src/Entity/Usuario.php +++ b/src/Entity/Usuario.php @@ -47,7 +47,7 @@ class Usuario private $sexo; /** - * @ORM\OneToOne(targetEntity="App\Entity\Endereco", inversedBy="cliente") + * @ORM\OneToOne(targetEntity="App\Entity\Endereco", inversedBy="cliente", cascade={"persist"}) * @ORM\JoinColumn(name="id_endereco", referencedColumnName="id", unique=true, nullable=true) */ private $endereco; @@ -191,7 +191,7 @@ public function getEndereco() /** * @param mixed $endereco */ - public function setEndereco($endereco): void + public function setEndereco(Endereco $endereco): void { $this->endereco = $endereco; } diff --git a/src/Forms/EnderecoType.php b/src/Forms/EnderecoType.php index 14cab63..736e23b 100755 --- a/src/Forms/EnderecoType.php +++ b/src/Forms/EnderecoType.php @@ -3,6 +3,7 @@ namespace App\Forms; +use App\Entity\Endereco; use App\Entity\Usuario; use function PHPSTORM_META\type; use Symfony\Component\Form\AbstractType; @@ -46,7 +47,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('cidade', TextType::class, [ 'label' => 'Cidade:', ]) - ->add('ddd', TextType::class, [ + ->add('dddTelefone', TextType::class, [ 'label' => 'DDD:', ]) ->add('telefone', TextType::class, [ @@ -67,7 +68,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - 'data_class' => Usuario::class, + 'data_class' => Endereco::class, ]); } } diff --git a/src/Forms/UsuarioType.php b/src/Forms/UsuarioType.php index ba01612..b5b77a0 100755 --- a/src/Forms/UsuarioType.php +++ b/src/Forms/UsuarioType.php @@ -24,8 +24,8 @@ class UsuarioType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->setAction('../usuario') - ->setMethod('POST') +// ->setAction('../usuario') +// ->setMethod('POST') ->add('nome', TextType::class, [ 'label' => 'Nome' ]) @@ -51,6 +51,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('tipoUsuario', TextType::class, [ 'label' => 'Tipo De usuário', ]) + ->add('endereco', EnderecoType::class) ; } diff --git a/templates/base.html.twig b/templates/base.html.twig index 884ced9..1bbb6f3 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -66,7 +66,7 @@
@@ -81,7 +81,7 @@
From 90d287e7491a19eba4684076be6b262e68bf33a3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 1 Jun 2019 18:09:55 -0300 Subject: [PATCH 08/23] cadastro de imoveis --- data/database.sqlite | Bin 12288 -> 16384 bytes src/Controller/ImovelController.php | 44 +++++++ src/Controller/UsuarioController.php | 2 +- src/Entity/Imovel.php | 168 +++++++++++++++++++++++++++ src/Forms/ImovelType.php | 60 ++++++++++ templates/base.html.twig | 2 +- templates/imovel_cadastro.html.twig | 31 +++++ 7 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 src/Controller/ImovelController.php create mode 100644 src/Entity/Imovel.php create mode 100755 src/Forms/ImovelType.php create mode 100644 templates/imovel_cadastro.html.twig diff --git a/data/database.sqlite b/data/database.sqlite index bc2a424733342d88f5b69c11bedae4bd14475d9d..600fa9052fbcb59fd7d2e960c5d02ce2b3676926 100644 GIT binary patch delta 260 zcmZojXlP)ZAT21!z`(!)#4x}*QO8(VkU>u)lNTt&%w531m&dc0yI^DCKQ8?yFJ^Xe zNlC_*{F20^oYc(R{Ib*>2+86czj8 B3HAU0 diff --git a/src/Controller/ImovelController.php b/src/Controller/ImovelController.php new file mode 100644 index 0000000..2687cac --- /dev/null +++ b/src/Controller/ImovelController.php @@ -0,0 +1,44 @@ +createForm(ImovelType::class, $imovel); + $form->handleRequest($request); + + if ($form->isSubmitted()) { + $imovel = $form->getData(); + $em = $this->getDoctrine()->getManager(); + $em->persist($imovel); + $em->flush(); + + return $this->redirectToRoute('index'); + } + + return $this->render('imovel_cadastro.html.twig', [ + 'form' => $form->createView() + ]); + + } + +} \ No newline at end of file diff --git a/src/Controller/UsuarioController.php b/src/Controller/UsuarioController.php index c2040be..9d23a9e 100644 --- a/src/Controller/UsuarioController.php +++ b/src/Controller/UsuarioController.php @@ -18,7 +18,7 @@ class UsuarioController extends AbstractController /** * @Route("/usuario", name="usuario_novo") */ - public function novoUsuario(Request $request) + public function cadastroUsuario(Request $request) { $usuario = new Usuario(); $form = $this->createForm(UsuarioType::class, $usuario); diff --git a/src/Entity/Imovel.php b/src/Entity/Imovel.php new file mode 100644 index 0000000..1a76add --- /dev/null +++ b/src/Entity/Imovel.php @@ -0,0 +1,168 @@ +id; + } + + /** + * @param mixed $id + */ + public function setId($id): void + { + $this->id = $id; + } + + /** + * @return mixed + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param mixed $status + */ + public function setStatus($status): void + { + $this->status = $status; + } + + /** + * @return mixed + */ + public function getCaracteristicas() + { + return $this->caracteristicas; + } + + /** + * @param mixed $caracteristicas + */ + public function setCaracteristicas($caracteristicas): void + { + $this->caracteristicas = $caracteristicas; + } + + /** + * @return mixed + */ + public function getObservacao() + { + return $this->observacao; + } + + /** + * @param mixed $observacao + */ + public function setObservacao($observacao): void + { + $this->observacao = $observacao; + } + + /** + * @return mixed + */ + public function getTipoImovel() + { + return $this->tipoImovel; + } + + /** + * @param mixed $tipoImovel + */ + public function setTipoImovel($tipoImovel): void + { + $this->tipoImovel = $tipoImovel; + } + + /** + * @return mixed + */ + public function getDtCadastro() + { + return $this->dtCadastro; + } + + /** + * @param mixed $dtCadastro + */ + public function setDtCadastro($dtCadastro): void + { + $this->dtCadastro = $dtCadastro; + } + + /** + * @return mixed + */ + public function getEndereco() + { + return $this->endereco; + } + + /** + * @param mixed $endereco + */ + public function setEndereco($endereco): void + { + $this->endereco = $endereco; + } + +// /** +// * @ORM\OneToMany(targetEntity="Entity\contratoLocacao", mappedBy="imovel") +// */ +// private $contratoLocacao; +// +// /** +// * @ORM\OneToMany(targetEntity="Entity\ContratoAdm", mappedBy="imovel") +// */ +// private $contratoAdm; +} \ No newline at end of file diff --git a/src/Forms/ImovelType.php b/src/Forms/ImovelType.php new file mode 100755 index 0000000..9890434 --- /dev/null +++ b/src/Forms/ImovelType.php @@ -0,0 +1,60 @@ +setAction('../usuario') +// ->setMethod('POST') + ->add('status', TextType::class, [ + 'label' => 'Status' + ]) + ->add('caracteristicas', TextType::class, [ + 'label' => 'Caracterisiticas do Imovel', + ]) + ->add('observacao', TextType::class, [ + 'label' => 'Observações Geral', + ]) + ->add('tipoImovel', TextType::class, [ + 'label' => 'Tipo do Imovel', + ]) + ->add('dtCadastro', DateType::class, [ + 'label' => 'Data de Cadastro', + 'widget' => 'single_text', + 'attr' => ['class' => 'js-datepicker'], + ]) + ->add('endereco', EnderecoType::class) + ; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Imovel::class, + ]); + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index 1bbb6f3..2fa13f8 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -67,7 +67,7 @@ diff --git a/templates/imovel_cadastro.html.twig b/templates/imovel_cadastro.html.twig new file mode 100644 index 0000000..9e378da --- /dev/null +++ b/templates/imovel_cadastro.html.twig @@ -0,0 +1,31 @@ +{% include "base.html.twig" %} + + +
+ + +

Cadastro de Imóveis

+ +
+ {{ form_start(form) }} + {{ form_widget(form) }} + + + + {{ form_end(form) }} + +
+
+ + + +{% include "footer.html.twig" %}s + + + + + + + + + From ff0722358f62deff08168c53fe57d4bcc6a45974 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 1 Jun 2019 18:14:16 -0300 Subject: [PATCH 09/23] ajustes no cadastro do imovel --- data/database.sqlite | Bin 16384 -> 16384 bytes src/Entity/Imovel.php | 7 +++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/data/database.sqlite b/data/database.sqlite index 600fa9052fbcb59fd7d2e960c5d02ce2b3676926..ff69e78d2cfeef72cdf24b131d6d7f1e94a37250 100644 GIT binary patch delta 151 zcmZo@U~Fh$oFL68G*QNxRfs`PX2Zsm1^fbRd>a|~&-2gb58#*Md&swOv!cLUK7Ktm zUIt+Vm~0>~&tzo0`JtS$AR8n9eg^*in*|NF@;llyaxjS68jA`uh9#!wmlUNID-@O{ s7M0`|DKd5o8kj2>7+8T(a$<3!p^-5g053@ Date: Sat, 1 Jun 2019 18:43:13 -0300 Subject: [PATCH 10/23] lista de imoveis --- src/Controller/ImovelController.php | 15 ++++- src/Entity/Endereco.php | 8 +-- src/Entity/Imovel.php | 4 +- templates/base.html.twig | 2 +- templates/listar_imoveis.html.twig | 92 +++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 templates/listar_imoveis.html.twig diff --git a/src/Controller/ImovelController.php b/src/Controller/ImovelController.php index 2687cac..a35cd93 100644 --- a/src/Controller/ImovelController.php +++ b/src/Controller/ImovelController.php @@ -14,7 +14,7 @@ class ImovelController extends AbstractController { /** - * @Route("imovel/cadastro", name="cadasto_imovel") + * @Route("/imovel/cadastro", name="cadasto_imovel") * * @param Request $request * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response @@ -41,4 +41,17 @@ public function cadastroImovel(Request $request) } + /** + * @Route("/imovel/listar", name="listar_imoveis") + */ + public function listarImoveis() + { + $em = $this->getDoctrine()->getManager(); + $imoveis = $em->getRepository(Imovel::class)->findAll(); + + return $this->render('listar_imoveis.html.twig', [ + 'imoveis' => $imoveis + ]); + } + } \ No newline at end of file diff --git a/src/Entity/Endereco.php b/src/Entity/Endereco.php index 05279ae..e78e8ea 100644 --- a/src/Entity/Endereco.php +++ b/src/Entity/Endereco.php @@ -76,10 +76,10 @@ class Endereco */ private $cliente; -// /** -// * @ORM\OneToOne(targetEntity="Entity\Imovel", mappedBy="endereco") -// */ -// private $imovel; + /** + * @ORM\OneToOne(targetEntity="App\Entity\Imovel", mappedBy="endereco") + */ + private $imovel; /** * @return mixed diff --git a/src/Entity/Imovel.php b/src/Entity/Imovel.php index 3e714ff..e50f78c 100644 --- a/src/Entity/Imovel.php +++ b/src/Entity/Imovel.php @@ -42,11 +42,13 @@ class Imovel private $dtCadastro; /** - * @ORM\OneToOne(targetEntity="App\Entity\Endereco", inversedBy="imovel", cascade={"persist"}) + * @ORM\OneToOne(targetEntity="App\Entity\Endereco", inversedBy="imovel", cascade={"persist"}, fetch="EAGER") * @ORM\JoinColumn(name="id_endereco", referencedColumnName="id", unique=true) */ private $endereco; + + /** * @return mixed */ diff --git a/templates/base.html.twig b/templates/base.html.twig index 2fa13f8..293cf23 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -82,7 +82,7 @@ diff --git a/templates/listar_imoveis.html.twig b/templates/listar_imoveis.html.twig new file mode 100644 index 0000000..e93031e --- /dev/null +++ b/templates/listar_imoveis.html.twig @@ -0,0 +1,92 @@ +{% include "base.html.twig" %} + + +
+ + +
+
+
Lista de Imovéis Cadastrados
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + {% for imovel in imoveis %} + + + + + + + + + + + {% endfor %} +
StatusCaracterisitcasObservacaoTipo do ImovelData CadastroBairroRua
StatusCaracterisitcasObservacaoTipo do ImovelData CadastroBairroRua
{{ imovel.status }}r{{ imovel.caracteristicas }}{{ imovel.observacao }}{{ imovel.tipoImovel }}{{ imovel.dtCadastro|date("m/d/Y") }}{{ imovel.endereco.bairro }}{{ imovel.endereco.logradouro }} + +
+
+
+
+ +
+
+ +{#
#} + + + + + + + + + + + + + + + + + + + + + +{% include "footer.html.twig" %}s + + + + + + + + + From f128894a0a3521d25d1565d5c4d8babe0eba6e2e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 09:46:52 -0300 Subject: [PATCH 11/23] choices para uf e status emovel --- data/database.sqlite | Bin 16384 -> 16384 bytes src/Forms/EnderecoType.php | 35 +++++++++++++++++++++++++++++++++-- src/Forms/ImovelType.php | 26 ++++++++++++++++++++++---- templates/base.html.twig | 2 +- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/data/database.sqlite b/data/database.sqlite index ff69e78d2cfeef72cdf24b131d6d7f1e94a37250..02a641dde6ecc8ff835ac098e3e242d15d534683 100644 GIT binary patch delta 143 zcmZo@U~Fh$oFL68JW=WSH+8e3Ks}#~6gw{i zKfjD)Bpeg delta 65 zcmZo@U~Fh$oFL68G*QNxQD|er5`F=WCSB6 diff --git a/src/Forms/EnderecoType.php b/src/Forms/EnderecoType.php index 736e23b..f577d5c 100755 --- a/src/Forms/EnderecoType.php +++ b/src/Forms/EnderecoType.php @@ -7,8 +7,10 @@ use App\Entity\Usuario; use function PHPSTORM_META\type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\EmailType; +use Symfony\Component\Form\Extension\Core\Type\TelType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -41,8 +43,37 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('complemento', TextType::class, [ 'label' => 'Complemento', ]) - ->add('uf', TextType::class, [ + ->add('uf', ChoiceType::class, [ 'label' => 'UF:', + 'choices' => [ + 'Acre' => 'AC', + 'Alagoas' => 'AL', + 'Amazonas' => 'AM', + 'Amapá' => 'AP', + 'Bahia' => 'BA', + 'Ceará' => 'CE', + 'Distrito Federal' => 'DF', + 'Espírito Santo' => 'ES', + 'Goiás' => 'GO', + 'Maranhão' => 'MA', + 'Mato Grosso' => 'MT', + 'Mato Grosso do Sul' => 'MS', + 'Minas Gerais' => 'MG', + 'Pará' => 'PA', + 'Paraíba' => 'PB', + 'Paraná' => 'PR', + 'Pernambuco' => 'PE', + 'Piauí' => 'PI', + 'Rio de Janeiro' => 'RJ', + 'Rio Grande do Norte' => 'RN', + 'Rio Grande do Sul' => 'RS', + 'Rondônia' => 'RO', + 'Roraima' => 'RR', + 'Santa Catarina' => 'SC', + 'São Paulo' => 'SP', + 'Sergipe' => 'SE', + 'Tocantins' => 'TO' + ], ]) ->add('cidade', TextType::class, [ 'label' => 'Cidade:', @@ -50,7 +81,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('dddTelefone', TextType::class, [ 'label' => 'DDD:', ]) - ->add('telefone', TextType::class, [ + ->add('telefone', TelType::class, [ 'label' => 'Telefone:', ]) ->add('dddCelular', TextType::class, [ diff --git a/src/Forms/ImovelType.php b/src/Forms/ImovelType.php index 9890434..14fb62a 100755 --- a/src/Forms/ImovelType.php +++ b/src/Forms/ImovelType.php @@ -6,6 +6,7 @@ use App\Entity\Imovel; use App\Entity\Usuario; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -27,8 +28,17 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder // ->setAction('../usuario') // ->setMethod('POST') - ->add('status', TextType::class, [ - 'label' => 'Status' + ->add('status', ChoiceType::class, [ + 'label' => 'Status', + 'choices' => [ + 'Disponivel' => 'disponivel', + 'Alugado' => 'alugado', + 'Em Manutenção' => 'Em Manutenção', + 'Vistoria' => 'Vistoria', + 'Sem Cotrato Adm' => 'Sem Cotrato Adm', + 'Sem Contrato de Locação' => 'Sem Contrato de Locação' + ] + ]) ->add('caracteristicas', TextType::class, [ 'label' => 'Caracterisiticas do Imovel', @@ -36,8 +46,16 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('observacao', TextType::class, [ 'label' => 'Observações Geral', ]) - ->add('tipoImovel', TextType::class, [ - 'label' => 'Tipo do Imovel', + ->add('tipoImovel', ChoiceType::class, [ + 'empty_data' => 'Casa', + 'choices' => [ + 'Casa' => 'Casa', + 'Apartamento' => 'Apartamento', + 'Galpão' => 'Calpão', + 'Terreno' => 'Terreno', + 'Prédio Comercial' => 'Prédio Comercial', + 'Loja em Shopping' => 'Loja em Shopping' + ] ]) ->add('dtCadastro', DateType::class, [ 'label' => 'Data de Cadastro', diff --git a/templates/base.html.twig b/templates/base.html.twig index 293cf23..78d9e01 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -21,7 +21,7 @@ Imobiliária - + From ed035bb793cfd0a35af94b2313b2f564b4e6196d Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 19:54:30 -0300 Subject: [PATCH 12/23] =?UTF-8?q?Google=20maps=20na=20visualiza=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20imovel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/database.sqlite | Bin 16384 -> 16384 bytes src/Controller/ImovelController.php | 29 +++++++ src/Forms/UsuarioType.php | 5 +- templates/base.html.twig | 11 +-- templates/footer.html.twig | 19 ++++- templates/imobiliaria.html.twig | 88 ++++++++------------- templates/imovel_visualizar.html.twig | 83 +++++++++++++++++++ templates/listar_portifolios.html.twig | 105 +++++++++++++++++++++++++ templates/listar_usuarios.html.twig | 3 +- templates/usuario_cadastro.html.twig | 12 +-- 10 files changed, 278 insertions(+), 77 deletions(-) create mode 100644 templates/imovel_visualizar.html.twig create mode 100644 templates/listar_portifolios.html.twig diff --git a/data/database.sqlite b/data/database.sqlite index 02a641dde6ecc8ff835ac098e3e242d15d534683..6e2c9a275c75976e8d8a18ad7d798a622e6eaebf 100644 GIT binary patch delta 375 zcmX|*zb^w}9LC>kNiI_FsUK;owBH6X=*iokSA<3}5Tr;fM0~kZ7uC19_m0G(lbKwa zNK8T^v552!Ff?XHvzg6iQ3lWR8J^^`Jk_dHtxD%1srRC9M(TaszE!$qs!7U=a-|fM zFnyBztnw+#xJs*|Cjs_9uJcqALs<*01V@^3LwP{k&qMuPyv&NEl;yFEzkl8 X0uOWm55Es|vk@@r4v~<4lXO3fsx2dc diff --git a/src/Controller/ImovelController.php b/src/Controller/ImovelController.php index a35cd93..5cbf296 100644 --- a/src/Controller/ImovelController.php +++ b/src/Controller/ImovelController.php @@ -54,4 +54,33 @@ public function listarImoveis() ]); } + /** + * @Route("/imovel/portifolios", name="listar_portifolios") + */ + public function imoveisPortifolios() + { + $em = $this->getDoctrine()->getManager(); + $imoveis = $em->getRepository(Imovel::class)->findAll(); + + return $this->render('listar_portifolios.html.twig', [ + 'imoveis' => $imoveis + ]); + } + + /** + * @Route("/imovel/visualizar/{id}", name="imovel_visualizar") + */ + public function imovelVisualizar(Request $request) + { + $id = $request->get('id'); + $em = $this->getDoctrine()->getManager(); + $imovel = $em->getRepository(Imovel::class)->find($id); + + return $this->render('imovel_visualizar.html.twig', [ + 'imovel' => $imovel + ]); + } + + + } \ No newline at end of file diff --git a/src/Forms/UsuarioType.php b/src/Forms/UsuarioType.php index b5b77a0..4d3c013 100755 --- a/src/Forms/UsuarioType.php +++ b/src/Forms/UsuarioType.php @@ -27,7 +27,10 @@ public function buildForm(FormBuilderInterface $builder, array $options): void // ->setAction('../usuario') // ->setMethod('POST') ->add('nome', TextType::class, [ - 'label' => 'Nome' + 'label' => 'Nome', + 'attr' => [ + 'class' => 'col-xs-6' + ] ]) ->add('CpfCnpj', TextType::class, [ 'label' => 'CpfCnpj', diff --git a/templates/base.html.twig b/templates/base.html.twig index 78d9e01..47e2e57 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -1,15 +1,5 @@ - - {% block head_css %} - - {% endblock %} - {% block head_js %} - - - - {% endblock %} - @@ -26,6 +16,7 @@ + diff --git a/templates/footer.html.twig b/templates/footer.html.twig index 40df4de..27695dc 100755 --- a/templates/footer.html.twig +++ b/templates/footer.html.twig @@ -25,14 +25,25 @@ - - + + - + - + + + + + + + + + + + + diff --git a/templates/imobiliaria.html.twig b/templates/imobiliaria.html.twig index 4de4a34..d9e7c2f 100644 --- a/templates/imobiliaria.html.twig +++ b/templates/imobiliaria.html.twig @@ -1,14 +1,14 @@ - + - Bem Vindo!! + Imobiliária @@ -19,68 +19,46 @@ - +
-
-

Cards

-
- - -
-
-
-
-
-
Casas para alugar a partir
-
R$150,000
-
-
- -
-
-
-
-
- - -
-
-
-
-
-
Aluguel por Temporada
-
R$2500,00
+ + +
+ +
+ +
+
+ +
+

Bem Vindo a Imobiliária

+ -
-
+
-
- +
- - - - - - - - - - \ No newline at end of file diff --git a/templates/imovel_visualizar.html.twig b/templates/imovel_visualizar.html.twig new file mode 100644 index 0000000..1d66bc5 --- /dev/null +++ b/templates/imovel_visualizar.html.twig @@ -0,0 +1,83 @@ + + + + + + + + + + + Imobiliária + + + + + + + + + + + + +
+ + +
+
+ + +
+

Dados do Imóvel

+
+ +
+ + + +
+
+
+
+
+
Características Gerais
+
{{imovel.tipoImovel }}
+
{{imovel.caracteristicas }}
+
{{imovel.observacao}}
+
+
+
+
+
+ +
+
+
+
+
+
Localização
+
Logradoura: {{ imovel.endereco.logradouro }}
+
Bairro: {{imovel.endereco.bairro }}
+
Numero: {{imovel.endereco.numero}}
+
Cidade: {{imovel.endereco.cidade}} Estado: {{imovel.endereco.uf}}
+
+
+
+
+
+ +
+ +
+
+ + + Voltar + +
+ +{#
#} + +{% include "footer.html.twig" %} \ No newline at end of file diff --git a/templates/listar_portifolios.html.twig b/templates/listar_portifolios.html.twig new file mode 100644 index 0000000..d5b76a4 --- /dev/null +++ b/templates/listar_portifolios.html.twig @@ -0,0 +1,105 @@ + + + + + + + + + + + Imobiliária + + + + + + + + + + + + +
+ + +
+
+ + +
+

Portifólio de Imóveis

+
+ +
+ + + {% for imovel in imoveis %} + +
+ {% if imovel.tipoImovel|upper == 'CASA' %} +
+ {% else %} +
+ {% endif %} +
+
+
+
{{ imovel.tipoImovel }}
+
{{imovel.caracteristicas }}
+
{{imovel.observacao}}
+
+ + + +
+
+
+
+ {% endfor %} + + {# {% for imovel in imoveis %}#} +{#
#} +{#
#} +{#

{{imovel.status}}

#} +{#

{{imovel.endereco.logradouro}}

#} +{#
#} +{#
#} +{# {% endfor %}#} + +
+
+ +{#
#} + + + + + + + + + + + + + + + + + + + + + +{% include "footer.html.twig" %}s + + + + + + + + + diff --git a/templates/listar_usuarios.html.twig b/templates/listar_usuarios.html.twig index 3cc3aa8..3ca8550 100644 --- a/templates/listar_usuarios.html.twig +++ b/templates/listar_usuarios.html.twig @@ -2,7 +2,6 @@
-
@@ -36,7 +35,7 @@ {% for usuario in usuarios %} - {{ usuario.nome }}r + {{ usuario.nome }} {{ usuario.cpfCnpj }} {{ usuario.email }} {{ usuario.sexo }} diff --git a/templates/usuario_cadastro.html.twig b/templates/usuario_cadastro.html.twig index 8656ffe..e5b4a59 100644 --- a/templates/usuario_cadastro.html.twig +++ b/templates/usuario_cadastro.html.twig @@ -6,14 +6,16 @@

Cadastro de Usuários

-
- {{ form_start(form) }} - {{ form_widget(form) }} +
+
+ {{ form_start(form) }} + {{ form_widget(form) }} - + - {{ form_end(form) }} + {{ form_end(form) }} +
From a43b75f41d943ab4379c99e3a6f4a47045354936 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 20:05:52 -0300 Subject: [PATCH 13/23] =?UTF-8?q?Google=20maps=20na=20visualiza=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20imovel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/database.sqlite | Bin 16384 -> 16384 bytes templates/imovel_visualizar.html.twig | 15 ++++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/data/database.sqlite b/data/database.sqlite index 6e2c9a275c75976e8d8a18ad7d798a622e6eaebf..db5b0ac85a43f5a3557fedbedf19ab5a2ea2207a 100644 GIT binary patch delta 273 zcmZo@U~Fh$oFL68JyFJ)QF>#-5`HmG-ph>q=lN&z2k^`BJ>uKQHMX6P(3Mr`yxrv$ihDOGw7G?%U zx&{UYi3KJ33Wf$oUipU?=PLxH78mCy26$RRfdvZKY%X_JkcWk@iGhDVe+l1jzNXEB z21R_14^$?i3;h7MTzODxs&JG%SnYL=HwSCq~t4r3@J^`Q3z5oHZagJFyP$$+m4kH E04EAj-v9sr delta 74 zcmZo@U~Fh$oFL68HBrWyQEFqt5`Ga5K66I?^Zc{<1Ni0m9`SADo62XtS
- -
- -
-
- - Voltar - +
+ +
+ + Voltar + {#
#} From 3d9010d3bf6c36249c59c55940dd22cf3b6d3a0d Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 20:15:01 -0300 Subject: [PATCH 14/23] =?UTF-8?q?Google=20maps=20na=20visualiza=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20imovel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/ImobiliariaController.php | 10 ++++ templates/imobiliaria.html.twig | 60 ++++------------------ templates/index.html.twig | 64 ++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 templates/index.html.twig diff --git a/src/Controller/ImobiliariaController.php b/src/Controller/ImobiliariaController.php index 6018cd0..20be8c6 100644 --- a/src/Controller/ImobiliariaController.php +++ b/src/Controller/ImobiliariaController.php @@ -15,6 +15,16 @@ class ImobiliariaController extends AbstractController * @Route("/", name="index") */ public function index() + { + + return $this->render('index.html.twig'); + + } + + /** + * @Route("dashboard", name="dashboard") + */ + public function dashboard() { return $this->render('imobiliaria.html.twig'); diff --git a/templates/imobiliaria.html.twig b/templates/imobiliaria.html.twig index d9e7c2f..6a02699 100644 --- a/templates/imobiliaria.html.twig +++ b/templates/imobiliaria.html.twig @@ -1,64 +1,26 @@ - +{% include "base.html.twig" %} - + +
- - - - - + +

Bem vindo a área logado do sistema

+

Escolha no menu lateral a funcionalidade desejada

- Imobiliária +
- - - - - - - - +
+
- + -
+{% include "footer.html.twig" %}s - -
-
-
-
-
-

Bem Vindo a Imobiliária

- -
-
- - \ No newline at end of file diff --git a/templates/index.html.twig b/templates/index.html.twig new file mode 100644 index 0000000..dd6baca --- /dev/null +++ b/templates/index.html.twig @@ -0,0 +1,64 @@ + + + + + + + + + + + Imobiliária + + + + + + + + + + + + +
+ + +
+ +
+ +
+
+ +
+

Bem Vindo a Imobiliária

+ + +
+ +
+ + + + \ No newline at end of file From 17f85f76e94a56b3e4fee9b3fea2386f063ca302 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 20:17:36 -0300 Subject: [PATCH 15/23] Removendo caracter fantasma --- templates/listar_imoveis.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/listar_imoveis.html.twig b/templates/listar_imoveis.html.twig index e93031e..6af1973 100644 --- a/templates/listar_imoveis.html.twig +++ b/templates/listar_imoveis.html.twig @@ -38,7 +38,7 @@ {% for imovel in imoveis %} - {{ imovel.status }}r + {{ imovel.status }} {{ imovel.caracteristicas }} {{ imovel.observacao }} {{ imovel.tipoImovel }} From a3ef279fc7a55f89374268d5f5d5b062eb24e734 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 2 Jun 2019 21:06:52 -0300 Subject: [PATCH 16/23] Ajustes nas tabelas --- templates/base.html.twig | 2 +- templates/footer.html.twig | 4 -- templates/imobiliaria.html.twig | 88 +++++++++++++++++++++++++++++ templates/index.html.twig | 38 ++++++------- templates/listar_usuarios.html.twig | 16 ++++-- 5 files changed, 120 insertions(+), 28 deletions(-) diff --git a/templates/base.html.twig b/templates/base.html.twig index 47e2e57..d1b040f 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -41,7 +41,7 @@ diff --git a/templates/footer.html.twig b/templates/footer.html.twig index 27695dc..c495e02 100755 --- a/templates/footer.html.twig +++ b/templates/footer.html.twig @@ -34,10 +34,6 @@ - - - - diff --git a/templates/imobiliaria.html.twig b/templates/imobiliaria.html.twig index 6a02699..1cb9166 100644 --- a/templates/imobiliaria.html.twig +++ b/templates/imobiliaria.html.twig @@ -7,11 +7,99 @@

Bem vindo a área logado do sistema

Escolha no menu lateral a funcionalidade desejada

+
+ + +
+
+ +
+
Earnings Overview
+ +
+ +
+
+ +
+
+
+
+ + +
+
+ +
+
Revenue Sources
+ +
+ +
+
+ +
+
+ + Direct + + + Social + + + Referral + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + {% include "footer.html.twig" %}s diff --git a/templates/index.html.twig b/templates/index.html.twig index dd6baca..3256189 100644 --- a/templates/index.html.twig +++ b/templates/index.html.twig @@ -31,27 +31,27 @@
-
-

Bem Vindo a Imobiliária

-
-
- +
+

Bem Vindo a Imobiliária

+
+ diff --git a/templates/listar_usuarios.html.twig b/templates/listar_usuarios.html.twig index 3ca8550..6831f09 100644 --- a/templates/listar_usuarios.html.twig +++ b/templates/listar_usuarios.html.twig @@ -1,5 +1,13 @@ {% include "base.html.twig" %} + + + + + + + +
@@ -32,7 +40,6 @@ - {% for usuario in usuarios %} {{ usuario.nome }} @@ -44,6 +51,7 @@ + {% endfor %}
@@ -56,6 +64,9 @@ {#
#} + + + @@ -70,9 +81,6 @@ - - - {% include "footer.html.twig" %}s From c5da68095746129ff61bcb69b8a42e4f65ba920f Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 3 Jun 2019 20:49:02 -0300 Subject: [PATCH 17/23] Ajustes do layout do fromulario --- data/database.sqlite | Bin 16384 -> 16384 bytes public/js/demo/chart-area-demo.js | 2 +- public/js/demo/jquery.dataTables.js | 15296 +++++++++++++++++++++++++ src/Forms/UsuarioType.php | 8 +- templates/imobiliaria.html.twig | 4 +- templates/listar_usuarios.html.twig | 35 +- templates/usuario_cadastro.html.twig | 88 +- 7 files changed, 15405 insertions(+), 28 deletions(-) create mode 100644 public/js/demo/jquery.dataTables.js diff --git a/data/database.sqlite b/data/database.sqlite index db5b0ac85a43f5a3557fedbedf19ab5a2ea2207a..d6b5146909fcc28ecb935fa36d059743e97b6d8e 100644 GIT binary patch delta 446 zcmZo@U~Fh$oFL68H&Mo!QEp?x5`GyT-YiD`^Zc{<1Ni0m9`SADo62X-dzp6~Z!d4w zW<>!n-g-qIUItM?FyIG*#9|qMhsS||=LUZaKPTT|z7jq)-s`-ryrw+O z{Kt44fX-ClsdwbzVGtEoR5TT4U=U;kIuYoIL?Z)3OI-s~U1I|X%S_k6I3qPDGv6US zH!(BE2n6(!^K(Ipi+O^%co@``6&1DRK}NVGCS~R;I42gR#-5`HmG-ph>q=lN&z2k^`BJ>uKQHUN8PXU)VDk-~TTG0B6B~UO H83+IX{%;*t diff --git a/public/js/demo/chart-area-demo.js b/public/js/demo/chart-area-demo.js index 0bb9c4d..d753da0 100644 --- a/public/js/demo/chart-area-demo.js +++ b/public/js/demo/chart-area-demo.js @@ -1,4 +1,4 @@ -// Set new default font family and font color to mimic Bootstrap's default styling + // Set new default font family and font color to mimic Bootstrap's default styling Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'; Chart.defaults.global.defaultFontColor = '#858796'; diff --git a/public/js/demo/jquery.dataTables.js b/public/js/demo/jquery.dataTables.js new file mode 100644 index 0000000..3db866f --- /dev/null +++ b/public/js/demo/jquery.dataTables.js @@ -0,0 +1,15296 @@ +/*! DataTables 1.10.19 + * ©2008-2018 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary DataTables + * @description Paginate, search and order HTML tables + * @version 1.10.19 + * @file jquery.dataTables.js + * @author SpryMedia Ltd + * @contact www.datatables.net + * @copyright Copyright 2008-2018 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ + +(function( factory ) { + "use strict"; + + if ( typeof define === 'function' && define.amd ) { + // AMD + define( ['jquery'], function ( $ ) { + return factory( $, window, document ); + } ); + } + else if ( typeof exports === 'object' ) { + // CommonJS + module.exports = function (root, $) { + if ( ! root ) { + // CommonJS environments without a window global must pass a + // root. This will give an error otherwise + root = window; + } + + if ( ! $ ) { + $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window + require('jquery') : + require('jquery')( root ); + } + + return factory( $, root, root.document ); + }; + } + else { + // Browser + factory( jQuery, window, document ); + } +} +(function( $, window, document, undefined ) { + "use strict"; + + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a highly + * flexible tool, based upon the foundations of progressive enhancement, + * which will add advanced interaction controls to any HTML table. For a + * full list of features please refer to + * [DataTables.net](href="http://datatables.net). + * + * Note that the `DataTable` object is not a global variable but is aliased + * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may + * be accessed. + * + * @class + * @param {object} [init={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.7+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "paginate": false, + * "sort": false + * } ); + * } ); + */ + var DataTable = function ( options ) + { + /** + * Perform a jQuery selector action on the table's TR elements (from the tbody) and + * return the resulting jQuery object. + * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on + * @param {object} [oOpts] Optional parameters for modifying the rows to be included + * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter + * criterion ("applied") or all TR elements (i.e. no filter). + * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. + * Can be either 'current', whereby the current sorting of the table is used, or + * 'original' whereby the original order the data was read into the table is used. + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page + * ("current") or not ("all"). If 'current' is given, then order is assumed to be + * 'current' and filter is 'applied', regardless of what they might be given as. + * @returns {object} jQuery object, filtered by the given selector. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Highlight every second row + * oTable.$('tr:odd').css('backgroundColor', 'blue'); + * } ); + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Filter to rows with 'Webkit' in them, add a background colour and then + * // remove the filter, thus highlighting the 'Webkit' rows only. + * oTable.fnFilter('Webkit'); + * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); + * oTable.fnFilter(''); + * } ); + */ + this.$ = function ( sSelector, oOpts ) + { + return this.api(true).$( sSelector, oOpts ); + }; + + + /** + * Almost identical to $ in operation, but in this case returns the data for the matched + * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes + * rather than any descendants, so the data can be obtained for the row/cell. If matching + * rows are found, the data returned is the original data array/object that was used to + * create the row (or a generated array if from a DOM source). + * + * This method is often useful in-combination with $ where both functions are given the + * same parameters and the array indexes will match identically. + * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on + * @param {object} [oOpts] Optional parameters for modifying the rows to be included + * @param {string} [oOpts.filter=none] Select elements that meet the current filter + * criterion ("applied") or all elements (i.e. no filter). + * @param {string} [oOpts.order=current] Order of the data in the processed array. + * Can be either 'current', whereby the current sorting of the table is used, or + * 'original' whereby the original order the data was read into the table is used. + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page + * ("current") or not ("all"). If 'current' is given, then order is assumed to be + * 'current' and filter is 'applied', regardless of what they might be given as. + * @returns {array} Data for the matched elements. If any elements, as a result of the + * selector, were not TR, TD or TH elements in the DataTable, they will have a null + * entry in the array. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Get the data from the first row in the table + * var data = oTable._('tr:first'); + * + * // Do something useful with the data + * alert( "First cell is: "+data[0] ); + * } ); + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Filter to 'Webkit' and get all data for + * oTable.fnFilter('Webkit'); + * var data = oTable._('tr', {"search": "applied"}); + * + * // Do something with the data + * alert( data.length+" rows matched the search" ); + * } ); + */ + this._ = function ( sSelector, oOpts ) + { + return this.api(true).rows( sSelector, oOpts ).data(); + }; + + + /** + * Create a DataTables Api instance, with the currently selected tables for + * the Api's context. + * @param {boolean} [traditional=false] Set the API instance's context to be + * only the table referred to by the `DataTable.ext.iApiIndex` option, as was + * used in the API presented by DataTables 1.9- (i.e. the traditional mode), + * or if all tables captured in the jQuery object should be used. + * @return {DataTables.Api} + */ + this.api = function ( traditional ) + { + return traditional ? + new _Api( + _fnSettingsFromNode( this[ _ext.iApiIndex ] ) + ) : + new _Api( this ); + }; + + + /** + * Add a single new row or multiple rows of data to the table. Please note + * that this is suitable for client-side processing only - if you are using + * server-side processing (i.e. "bServerSide": true), then to add data, you + * must add it to the data source, i.e. the server-side, through an Ajax call. + * @param {array|object} data The data to be added to the table. This can be: + *
    + *
  • 1D array of data - add a single row with the data provided
  • + *
  • 2D array of arrays - add multiple rows in a single call
  • + *
  • object - data object when using mData
  • + *
  • array of objects - multiple data objects when using mData
  • + *
+ * @param {bool} [redraw=true] redraw the table or not + * @returns {array} An array of integers, representing the list of indexes in + * aoData ({@link DataTable.models.oSettings}) that have been added to + * the table. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * // Global var for counter + * var giCount = 2; + * + * $(document).ready(function() { + * $('#example').dataTable(); + * } ); + * + * function fnClickAddRow() { + * $('#example').dataTable().fnAddData( [ + * giCount+".1", + * giCount+".2", + * giCount+".3", + * giCount+".4" ] + * ); + * + * giCount++; + * } + */ + this.fnAddData = function( data, redraw ) + { + var api = this.api( true ); + + /* Check if we want to add multiple rows or not */ + var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ? + api.rows.add( data ) : + api.row.add( data ); + + if ( redraw === undefined || redraw ) { + api.draw(); + } + + return rows.flatten().toArray(); + }; + + + /** + * This function will make DataTables recalculate the column sizes, based on the data + * contained in the table and the sizes applied to the columns (in the DOM, CSS or + * through the sWidth parameter). This can be useful when the width of the table's + * parent element changes (for example a window resize). + * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sScrollY": "200px", + * "bPaginate": false + * } ); + * + * $(window).on('resize', function () { + * oTable.fnAdjustColumnSizing(); + * } ); + * } ); + */ + this.fnAdjustColumnSizing = function ( bRedraw ) + { + var api = this.api( true ).columns.adjust(); + var settings = api.settings()[0]; + var scroll = settings.oScroll; + + if ( bRedraw === undefined || bRedraw ) { + api.draw( false ); + } + else if ( scroll.sX !== "" || scroll.sY !== "" ) { + /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ + _fnScrollDraw( settings ); + } + }; + + + /** + * Quickly and simply clear a table + * @param {bool} [bRedraw=true] redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) + * oTable.fnClearTable(); + * } ); + */ + this.fnClearTable = function( bRedraw ) + { + var api = this.api( true ).clear(); + + if ( bRedraw === undefined || bRedraw ) { + api.draw(); + } + }; + + + /** + * The exact opposite of 'opening' a row, this function will close any rows which + * are currently 'open'. + * @param {node} nTr the table row to 'close' + * @returns {int} 0 on success, or 1 if failed (can't find the row) + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnClose = function( nTr ) + { + this.api( true ).row( nTr ).child.hide(); + }; + + + /** + * Remove a row for the table + * @param {mixed} target The index of the row from aoData to be deleted, or + * the TR element you want to delete + * @param {function|null} [callBack] Callback function + * @param {bool} [redraw=true] Redraw the table or not + * @returns {array} The row that was deleted + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Immediately remove the first row + * oTable.fnDeleteRow( 0 ); + * } ); + */ + this.fnDeleteRow = function( target, callback, redraw ) + { + var api = this.api( true ); + var rows = api.rows( target ); + var settings = rows.settings()[0]; + var data = settings.aoData[ rows[0][0] ]; + + rows.remove(); + + if ( callback ) { + callback.call( this, settings, data ); + } + + if ( redraw === undefined || redraw ) { + api.draw(); + } + + return data; + }; + + + /** + * Restore the table to it's original state in the DOM by removing all of DataTables + * enhancements, alterations to the DOM structure of the table and event listeners. + * @param {boolean} [remove=false] Completely remove the table from the DOM + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * // This example is fairly pointless in reality, but shows how fnDestroy can be used + * var oTable = $('#example').dataTable(); + * oTable.fnDestroy(); + * } ); + */ + this.fnDestroy = function ( remove ) + { + this.api( true ).destroy( remove ); + }; + + + /** + * Redraw the table + * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) + * oTable.fnDraw(); + * } ); + */ + this.fnDraw = function( complete ) + { + // Note that this isn't an exact match to the old call to _fnDraw - it takes + // into account the new data, but can hold position. + this.api( true ).draw( complete ); + }; + + + /** + * Filter the input based on data + * @param {string} sInput String to filter the table on + * @param {int|null} [iColumn] Column to limit filtering to + * @param {bool} [bRegex=false] Treat as regular expression or not + * @param {bool} [bSmart=true] Perform smart filtering or not + * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) + * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sometime later - filter... + * oTable.fnFilter( 'test string' ); + * } ); + */ + this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) + { + var api = this.api( true ); + + if ( iColumn === null || iColumn === undefined ) { + api.search( sInput, bRegex, bSmart, bCaseInsensitive ); + } + else { + api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); + } + + api.draw(); + }; + + + /** + * Get the data for the whole table, an individual row or an individual cell based on the + * provided parameters. + * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as + * a TR node then the data source for the whole row will be returned. If given as a + * TD/TH cell node then iCol will be automatically calculated and the data for the + * cell returned. If given as an integer, then this is treated as the aoData internal + * data index for the row (see fnGetPosition) and the data for that row used. + * @param {int} [col] Optional column index that you want the data of. + * @returns {array|object|string} If mRow is undefined, then the data for all rows is + * returned. If mRow is defined, just data for that row, and is iCol is + * defined, only data for the designated cell is returned. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * // Row data + * $(document).ready(function() { + * oTable = $('#example').dataTable(); + * + * oTable.$('tr').click( function () { + * var data = oTable.fnGetData( this ); + * // ... do something with the array / object of data for the row + * } ); + * } ); + * + * @example + * // Individual cell data + * $(document).ready(function() { + * oTable = $('#example').dataTable(); + * + * oTable.$('td').click( function () { + * var sData = oTable.fnGetData( this ); + * alert( 'The cell clicked on had the value of '+sData ); + * } ); + * } ); + */ + this.fnGetData = function( src, col ) + { + var api = this.api( true ); + + if ( src !== undefined ) { + var type = src.nodeName ? src.nodeName.toLowerCase() : ''; + + return col !== undefined || type == 'td' || type == 'th' ? + api.cell( src, col ).data() : + api.row( src ).data() || null; + } + + return api.data().toArray(); + }; + + + /** + * Get an array of the TR nodes that are used in the table's body. Note that you will + * typically want to use the '$' API method in preference to this as it is more + * flexible. + * @param {int} [iRow] Optional row index for the TR element you want + * @returns {array|node} If iRow is undefined, returns an array of all TR elements + * in the table's body, or iRow is defined, just the TR element requested. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Get the nodes from the table + * var nNodes = oTable.fnGetNodes( ); + * } ); + */ + this.fnGetNodes = function( iRow ) + { + var api = this.api( true ); + + return iRow !== undefined ? + api.row( iRow ).node() : + api.rows().nodes().flatten().toArray(); + }; + + + /** + * Get the array indexes of a particular cell from it's DOM element + * and column index including hidden columns + * @param {node} node this can either be a TR, TD or TH in the table's body + * @returns {int} If nNode is given as a TR, then a single index is returned, or + * if given as a cell, an array of [row index, column index (visible), + * column index (all)] is given. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * $('#example tbody td').click( function () { + * // Get the position of the current data from the node + * var aPos = oTable.fnGetPosition( this ); + * + * // Get the data array for this row + * var aData = oTable.fnGetData( aPos[0] ); + * + * // Update the data array and return the value + * aData[ aPos[1] ] = 'clicked'; + * this.innerHTML = 'clicked'; + * } ); + * + * // Init DataTables + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnGetPosition = function( node ) + { + var api = this.api( true ); + var nodeName = node.nodeName.toUpperCase(); + + if ( nodeName == 'TR' ) { + return api.row( node ).index(); + } + else if ( nodeName == 'TD' || nodeName == 'TH' ) { + var cell = api.cell( node ).index(); + + return [ + cell.row, + cell.columnVisible, + cell.column + ]; + } + return null; + }; + + + /** + * Check to see if a row is 'open' or not. + * @param {node} nTr the table row to check + * @returns {boolean} true if the row is currently open, false otherwise + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnIsOpen = function( nTr ) + { + return this.api( true ).row( nTr ).child.isShown(); + }; + + + /** + * This function will place a new row directly after a row which is currently + * on display on the page, with the HTML contents that is passed into the + * function. This can be used, for example, to ask for confirmation that a + * particular record should be deleted. + * @param {node} nTr The table row to 'open' + * @param {string|node|jQuery} mHtml The HTML to put into the row + * @param {string} sClass Class to give the new TD cell + * @returns {node} The row opened. Note that if the table row passed in as the + * first parameter, is not found in the table, this method will silently + * return. + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable; + * + * // 'open' an information row when a row is clicked on + * $('#example tbody tr').click( function () { + * if ( oTable.fnIsOpen(this) ) { + * oTable.fnClose( this ); + * } else { + * oTable.fnOpen( this, "Temporary row opened", "info_row" ); + * } + * } ); + * + * oTable = $('#example').dataTable(); + * } ); + */ + this.fnOpen = function( nTr, mHtml, sClass ) + { + return this.api( true ) + .row( nTr ) + .child( mHtml, sClass ) + .show() + .child()[0]; + }; + + + /** + * Change the pagination - provides the internal logic for pagination in a simple API + * function. With this function you can have a DataTables table go to the next, + * previous, first or last pages. + * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" + * or page number to jump to (integer), note that page 0 is the first page. + * @param {bool} [bRedraw=true] Redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * oTable.fnPageChange( 'next' ); + * } ); + */ + this.fnPageChange = function ( mAction, bRedraw ) + { + var api = this.api( true ).page( mAction ); + + if ( bRedraw === undefined || bRedraw ) { + api.draw(false); + } + }; + + + /** + * Show a particular column + * @param {int} iCol The column whose display should be changed + * @param {bool} bShow Show (true) or hide (false) the column + * @param {bool} [bRedraw=true] Redraw the table or not + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Hide the second column after initialisation + * oTable.fnSetColumnVis( 1, false ); + * } ); + */ + this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) + { + var api = this.api( true ).column( iCol ).visible( bShow ); + + if ( bRedraw === undefined || bRedraw ) { + api.columns.adjust().draw(); + } + }; + + + /** + * Get the settings for a particular table for external manipulation + * @returns {object} DataTables settings object. See + * {@link DataTable.models.oSettings} + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * var oSettings = oTable.fnSettings(); + * + * // Show an example parameter from the settings + * alert( oSettings._iDisplayStart ); + * } ); + */ + this.fnSettings = function() + { + return _fnSettingsFromNode( this[_ext.iApiIndex] ); + }; + + + /** + * Sort the table by a particular column + * @param {int} iCol the data index to sort on. Note that this will not match the + * 'display index' if you have hidden data entries + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sort immediately with columns 0 and 1 + * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); + * } ); + */ + this.fnSort = function( aaSort ) + { + this.api( true ).order( aaSort ).draw(); + }; + + + /** + * Attach a sort listener to an element for a given column + * @param {node} nNode the element to attach the sort listener to + * @param {int} iColumn the column that a click on this node will sort on + * @param {function} [fnCallback] callback function when sort is run + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Sort on column 1, when 'sorter' is clicked on + * oTable.fnSortListener( document.getElementById('sorter'), 1 ); + * } ); + */ + this.fnSortListener = function( nNode, iColumn, fnCallback ) + { + this.api( true ).order.listener( nNode, iColumn, fnCallback ); + }; + + + /** + * Update a table cell or row - this method will accept either a single value to + * update the cell with, an array of values with one element for each column or + * an object in the same format as the original data source. The function is + * self-referencing in order to make the multi column updates easier. + * @param {object|array|string} mData Data to update the cell/row with + * @param {node|int} mRow TR element you want to update or the aoData index + * @param {int} [iColumn] The column to update, give as null or undefined to + * update a whole row. + * @param {bool} [bRedraw=true] Redraw the table or not + * @param {bool} [bAction=true] Perform pre-draw actions or not + * @returns {int} 0 on success, 1 on error + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell + * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row + * } ); + */ + this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) + { + var api = this.api( true ); + + if ( iColumn === undefined || iColumn === null ) { + api.row( mRow ).data( mData ); + } + else { + api.cell( mRow, iColumn ).data( mData ); + } + + if ( bAction === undefined || bAction ) { + api.columns.adjust(); + } + + if ( bRedraw === undefined || bRedraw ) { + api.draw(); + } + return 0; + }; + + + /** + * Provide a common method for plug-ins to check the version of DataTables being used, in order + * to ensure compatibility. + * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the + * formats "X" and "X.Y" are also acceptable. + * @returns {boolean} true if this version of DataTables is greater or equal to the required + * version, or false if this version of DataTales is not suitable + * @method + * @dtopt API + * @deprecated Since v1.10 + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * alert( oTable.fnVersionCheck( '1.9.0' ) ); + * } ); + */ + this.fnVersionCheck = _ext.fnVersionCheck; + + + var _that = this; + var emptyInit = options === undefined; + var len = this.length; + + if ( emptyInit ) { + options = {}; + } + + this.oApi = this.internal = _ext.internal; + + // Extend with old style plug-in API methods + for ( var fn in DataTable.ext.internal ) { + if ( fn ) { + this[fn] = _fnExternApiFunc(fn); + } + } + + this.each(function() { + // For each initialisation we want to give it a clean initialisation + // object that can be bashed around + var o = {}; + var oInit = len > 1 ? // optimisation for single table case + _fnExtend( o, options, true ) : + options; + + /*global oInit,_that,emptyInit*/ + var i=0, iLen, j, jLen, k, kLen; + var sId = this.getAttribute( 'id' ); + var bInitHandedOff = false; + var defaults = DataTable.defaults; + var $this = $(this); + + + /* Sanity check */ + if ( this.nodeName.toLowerCase() != 'table' ) + { + _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); + return; + } + + /* Backwards compatibility for the defaults */ + _fnCompatOpts( defaults ); + _fnCompatCols( defaults.column ); + + /* Convert the camel-case defaults to Hungarian */ + _fnCamelToHungarian( defaults, defaults, true ); + _fnCamelToHungarian( defaults.column, defaults.column, true ); + + /* Setting up the initialisation object */ + _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) ); + + + + /* Check to see if we are re-initialising a table */ + var allSettings = DataTable.settings; + for ( i=0, iLen=allSettings.length ; i').appendTo($this); + } + oSettings.nTHead = thead[0]; + + var tbody = $this.children('tbody'); + if ( tbody.length === 0 ) { + tbody = $('').appendTo($this); + } + oSettings.nTBody = tbody[0]; + + var tfoot = $this.children('tfoot'); + if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) { + // If we are a scrolling table, and no footer has been given, then we need to create + // a tfoot element for the caption element to be appended to + tfoot = $('').appendTo($this); + } + + if ( tfoot.length === 0 || tfoot.children().length === 0 ) { + $this.addClass( oClasses.sNoFooter ); + } + else if ( tfoot.length > 0 ) { + oSettings.nTFoot = tfoot[0]; + _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); + } + + /* Check if there is data passing into the constructor */ + if ( oInit.aaData ) { + for ( i=0 ; i/g; + + // This is not strict ISO8601 - Date.parse() is quite lax, although + // implementations differ between browsers. + var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/; + + // Escape regular expression special characters + var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); + + // http://en.wikipedia.org/wiki/Foreign_exchange_market + // - \u20BD - Russian ruble. + // - \u20a9 - South Korean Won + // - \u20BA - Turkish Lira + // - \u20B9 - Indian Rupee + // - R - Brazil (R$) and South Africa + // - fr - Swiss Franc + // - kr - Swedish krona, Norwegian krone and Danish krone + // - \u2009 is thin space and \u202F is narrow no-break space, both used in many + // - Ƀ - Bitcoin + // - Ξ - Ethereum + // standards as thousands separators. + var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi; + + + var _empty = function ( d ) { + return !d || d === true || d === '-' ? true : false; + }; + + + var _intVal = function ( s ) { + var integer = parseInt( s, 10 ); + return !isNaN(integer) && isFinite(s) ? integer : null; + }; + + // Convert from a formatted number with characters other than `.` as the + // decimal place, to a Javascript number + var _numToDecimal = function ( num, decimalPoint ) { + // Cache created regular expressions for speed as this function is called often + if ( ! _re_dic[ decimalPoint ] ) { + _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); + } + return typeof num === 'string' && decimalPoint !== '.' ? + num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : + num; + }; + + + var _isNumber = function ( d, decimalPoint, formatted ) { + var strType = typeof d === 'string'; + + // If empty return immediately so there must be a number if it is a + // formatted string (this stops the string "k", or "kr", etc being detected + // as a formatted number for currency + if ( _empty( d ) ) { + return true; + } + + if ( decimalPoint && strType ) { + d = _numToDecimal( d, decimalPoint ); + } + + if ( formatted && strType ) { + d = d.replace( _re_formatted_numeric, '' ); + } + + return !isNaN( parseFloat(d) ) && isFinite( d ); + }; + + + // A string without HTML in it can be considered to be HTML still + var _isHtml = function ( d ) { + return _empty( d ) || typeof d === 'string'; + }; + + + var _htmlNumeric = function ( d, decimalPoint, formatted ) { + if ( _empty( d ) ) { + return true; + } + + var html = _isHtml( d ); + return ! html ? + null : + _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? + true : + null; + }; + + + var _pluck = function ( a, prop, prop2 ) { + var out = []; + var i=0, ien=a.length; + + // Could have the test in the loop for slightly smaller code, but speed + // is essential here + if ( prop2 !== undefined ) { + for ( ; i') + .css( { + position: 'fixed', + top: 0, + left: $(window).scrollLeft()*-1, // allow for scrolling + height: 1, + width: 1, + overflow: 'hidden' + } ) + .append( + $('
') + .css( { + position: 'absolute', + top: 1, + left: 1, + width: 100, + overflow: 'scroll' + } ) + .append( + $('
') + .css( { + width: '100%', + height: 10 + } ) + ) + ) + .appendTo( 'body' ); + + var outer = n.children(); + var inner = outer.children(); + + // Numbers below, in order, are: + // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth + // + // IE6 XP: 100 100 100 83 + // IE7 Vista: 100 100 100 83 + // IE 8+ Windows: 83 83 100 83 + // Evergreen Windows: 83 83 100 83 + // Evergreen Mac with scrollbars: 85 85 100 85 + // Evergreen Mac without scrollbars: 100 100 100 100 + + // Get scrollbar width + browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth; + + // IE6/7 will oversize a width 100% element inside a scrolling element, to + // include the width of the scrollbar, while other browsers ensure the inner + // element is contained without forcing scrolling + browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100; + + // In rtl text layout, some browsers (most, but not all) will place the + // scrollbar on the left, rather than the right. + browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1; + + // IE8- don't provide height and width for getBoundingClientRect + browser.bBounding = n[0].getBoundingClientRect().width ? true : false; + + n.remove(); + } + + $.extend( settings.oBrowser, DataTable.__browser ); + settings.oScroll.iBarWidth = DataTable.__browser.barWidth; + } + + + /** + * Array.prototype reduce[Right] method, used for browsers which don't support + * JS 1.6. Done this way to reduce code size, since we iterate either way + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnReduce ( that, fn, init, start, end, inc ) + { + var + i = start, + value, + isSet = false; + + if ( init !== undefined ) { + value = init; + isSet = true; + } + + while ( i !== end ) { + if ( ! that.hasOwnProperty(i) ) { + continue; + } + + value = isSet ? + fn( value, that[i], i, that ) : + that[i]; + + isSet = true; + i += inc; + } + + return value; + } + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + // Add column to aoColumns array + var oDefaults = DataTable.defaults.column; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mData": oDefaults.mData ? oDefaults.mData : iCol, + idx: iCol + } ); + oSettings.aoColumns.push( oCol ); + + // Add search object for column specific search. Note that the `searchCols[ iCol ]` + // passed into extend can be undefined. This allows the user to give a default + // with only some of the parameters defined, and also not give a default + var searchCols = oSettings.aoPreSearchCols; + searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); + + // Use the default column options function to initialise classes etc + _fnColumnOptions( oSettings, iCol, $(nTh).data() ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable etc + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + var oClasses = oSettings.oClasses; + var th = $(oCol.nTh); + + // Try to get width information from the DOM. We can't get it from CSS + // as we'd need to parse the CSS stylesheet. `width` option can override + if ( ! oCol.sWidthOrig ) { + // Width attribute + oCol.sWidthOrig = th.attr('width') || null; + + // Style attribute + var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); + if ( t ) { + oCol.sWidthOrig = t[1]; + } + } + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + // Backwards compatibility + _fnCompatCols( oOptions ); + + // Map camel case parameters to their Hungarian counterparts + _fnCamelToHungarian( DataTable.defaults.column, oOptions ); + + /* Backwards compatibility for mDataProp */ + if ( oOptions.mDataProp !== undefined && !oOptions.mData ) + { + oOptions.mData = oOptions.mDataProp; + } + + if ( oOptions.sType ) + { + oCol._sManualType = oOptions.sType; + } + + // `class` is a reserved word in Javascript, so we need to provide + // the ability to use a valid name for the camel case input + if ( oOptions.className && ! oOptions.sClass ) + { + oOptions.sClass = oOptions.className; + } + if ( oOptions.sClass ) { + th.addClass( oOptions.sClass ); + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + var mDataSrc = oCol.mData; + var mData = _fnGetObjectDataFn( mDataSrc ); + var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; + + var attrTest = function( src ) { + return typeof src === 'string' && src.indexOf('@') !== -1; + }; + oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( + attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) + ); + oCol._setter = null; + + oCol.fnGetData = function (rowData, type, meta) { + var innerData = mData( rowData, type, undefined, meta ); + + return mRender && type ? + mRender( innerData, type, rowData, meta ) : + innerData; + }; + oCol.fnSetData = function ( rowData, val, meta ) { + return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); + }; + + // Indicate if DataTables should read DOM data as an object or array + // Used in _fnGetRowElements + if ( typeof mDataSrc !== 'number' ) { + oSettings._rowReadObject = true; + } + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called + } + + /* Check that the class assignment is correct for sorting */ + var bAsc = $.inArray('asc', oCol.asSorting) !== -1; + var bDesc = $.inArray('desc', oCol.asSorting) !== -1; + if ( !oCol.bSortable || (!bAsc && !bDesc) ) + { + oCol.sSortingClass = oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( bAsc && !bDesc ) + { + oCol.sSortingClass = oClasses.sSortableAsc; + oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; + } + else if ( !bAsc && bDesc ) + { + oCol.sSortingClass = oClasses.sSortableDesc; + oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; + } + else + { + oCol.sSortingClass = oClasses.sSortable; + oCol.sSortingClassJUI = oClasses.sSortJUI; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( settings ) + { + /* Not interested in doing column width calculation if auto-width is disabled */ + if ( settings.oFeatures.bAutoWidth !== false ) + { + var columns = settings.aoColumns; + + _fnCalculateColumnWidths( settings ); + for ( var i=0 , iLen=columns.length ; i