Merge branch 'master' of https://github.com/thelia/thelia into coupon

* 'master' of https://github.com/thelia/thelia: (87 commits)
  Missing ajax-loader icon
  don't use alternative Logger in debugbar if debug is disabled
  Remove debug bar
  Move temporarily fontawesome's font into the web folder
  Add loader css
  fix product visibility comparaison parameter
  Change this page on public page
  Bug : Remove close tag </a>
  decode url before searching if it's a rewritten url
  Modification font-size of price elements
  add page View All
  Add button "add product to cart"
  Footer : Static to dynamic content
  Add order on attribute_combination loop
  Fix bug in Content Loop with "current_folder" params
  Creation of Content page
  Change path /customer/account into /account
  Change path :  /customer/update into /account/update  /password into /account/password
  CustomerUpdateForm - Extend CustomerCreation
  Update profile - new method [Not finished yet]
  ...
This commit is contained in:
gmorel
2013-10-20 21:11:58 +02:00
105 changed files with 6129 additions and 4013 deletions

BIN
composer.phar Executable file

Binary file not shown.

View File

@@ -41,6 +41,7 @@ class Tax extends BaseAction implements EventSubscriberInterface
$tax
->setDispatcher($this->getDispatcher())
->setRequirements($event->getRequirements())
->setType($event->getType())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
@@ -61,14 +62,14 @@ class Tax extends BaseAction implements EventSubscriberInterface
$tax
->setDispatcher($this->getDispatcher())
->setRequirements($event->getRequirements())
->setType($event->getType())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->save()
;
$tax->save();
$event->setTax($tax);
}
@@ -98,7 +99,6 @@ class Tax extends BaseAction implements EventSubscriberInterface
TheliaEvents::TAX_CREATE => array("create", 128),
TheliaEvents::TAX_UPDATE => array("update", 128),
TheliaEvents::TAX_DELETE => array("delete", 128),
);
}
}

View File

@@ -27,6 +27,7 @@ use Propel\Runtime\ActiveQuery\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Tax\TaxRuleEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Map\TaxRuleTableMap;
use Thelia\Model\TaxRuleCountry;
use Thelia\Model\TaxRuleCountryQuery;
use Thelia\Model\TaxRule as TaxRuleModel;
@@ -134,6 +135,23 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
}
}
/**
* @param TaxRuleEvent $event
*/
public function setDefault(TaxRuleEvent $event)
{
if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) {
TaxRuleQuery::create()->update(array(
"IsDefault" => 0
));
$taxRule->setIsDefault(1)->save();
$event->setTaxRule($taxRule);
}
}
/**
* {@inheritDoc}
*/
@@ -144,7 +162,7 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
TheliaEvents::TAX_RULE_UPDATE => array("update", 128),
TheliaEvents::TAX_RULE_TAXES_UPDATE => array("updateTaxes", 128),
TheliaEvents::TAX_RULE_DELETE => array("delete", 128),
TheliaEvents::TAX_RULE_SET_DEFAULT => array("setDefault", 128),
);
}
}

View File

@@ -55,6 +55,7 @@
<form name="thelia.install.step3" class="Thelia\Form\InstallStep3Form"/>
<form name="thelia.customer.creation" class="Thelia\Form\CustomerCreation"/>
<form name="thelia.customer.update" class="Thelia\Form\CustomerUpdateForm"/>
<form name="thelia.customer.modification" class="Thelia\Form\CustomerModification"/>
<form name="thelia.customer.lostpassword" class="Thelia\Form\CustomerLostPasswordForm"/>
@@ -132,6 +133,10 @@
<form name="thelia.admin.profile.modification" class="Thelia\Form\ProfileModificationForm"/>
<form name="thelia.admin.language.creation" class="Thelia\Form\LanguageCreationForm"/>
<form name="thelia.admin.admin-profile.creation" class="Thelia\Form\AdminProfileCreationForm"/>
<form name="thelia.admin.area.create" class="Thelia\Form\Area\AreaCreateForm"/>
<form name="thelia.admin.area.modification" class="Thelia\Form\Area\AreaModificationForm"/>
<form name="thelia.admin.area.country" class="Thelia\Form\Area\AreaCountryForm"/>

View File

@@ -870,6 +870,11 @@
<default key="_controller">Thelia\Controller\Admin\TaxRuleController::deleteAction</default>
</route>
<route id="admin.configuration.taxes-rules.set-default" path="/admin/configuration/taxes_rules/update/set_default/{tax_rule_id}">
<default key="_controller">Thelia\Controller\Admin\TaxRuleController::setDefaultAction</default>
<requirement key="tax_rule_id">\d+</requirement>
</route>
<!-- end tax rules management -->

View File

@@ -4,56 +4,75 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="home" path="/" >
<route id="home" path="/">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">index</default>
</route>
<!-- Customer routes -->
<!-- Search routes -->
<route id="search" path="/search">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">search</default>
</route>
<route id="view_all" path="/view_all" methods="get">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">view_all</default>
</route>
<!-- Customer routes : Register -->
<route id="customer.create.process" path="/register" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::createAction</default>
<default key="_view">register</default>
</route>
<route id="customer.create.view" path="/register">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">register</default>
</route>
<!-- Customer routes : Login -->
<route id="customer.login.process" path="/login" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::loginAction</default>
<default key="_view">login</default>
</route>
<route id="customer.login.view" path="/login">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">login</default>
</route>
<!-- Customer routes : Logout -->
<route id="customer.logout.process" path="/logout">
<default key="_controller">Thelia\Controller\Front\CustomerController::logoutAction</default>
</route>
<route id="customer.account.view" path="/customer/account">
<!-- Customer routes : Account -->
<route id="customer.account.view" path="/account">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account</default>
</route>
<route id="customer.create.process" path="/customer/create" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::createAction</default>
<default key="_view">register</default>
<route id="customer.update.view" path="/account/update" methods="get">
<default key="_controller">Thelia\Controller\Front\CustomerController::viewAction</default>
<default key="_view">account-update</default>
</route>
<route id="customer.update.process" path="/customer/update" methods="post">
<route id="customer.update.process" path="/account/update" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::updateAction</default>
</route>
<route id="customer.login.process" path="/customer/login" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::loginAction</default>
<default key="_view">login</default>
<default key="_view">account-update</default>
</route>
<route id="customer.password.retrieve.view" path="/password" methods="get">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">password</default>
</route>
<route id="customer.password.retrieve.process" path="/password" methods="post">
<route id="customer.password.retrieve.process" path="/account/password" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::newPasswordAction</default>
<default key="_view">password</default>
<default key="_view">account-password</default>
</route>
<route id="customer.password.retrieve.view" path="account/password" methods="get">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account-password</default>
</route>
<!-- end customer routes -->

View File

@@ -392,8 +392,6 @@ abstract class AbstractCrudController extends BaseAdminController
// Get the form field values
$data = $form->getData();
$dataType = $form->all();
$changeEvent = $this->getUpdateEvent($data);
$this->dispatch($this->updateEventIdentifier, $changeEvent);

View File

@@ -20,38 +20,20 @@
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\TaxEngine\TaxType;
use Thelia\Type\FloatToFloatArrayType;
use Thelia\Type\ModelValidIdType;
namespace Thelia\Controller\Admin;
/**
*
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*
* Class AdminProfileController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class featureSlicePercentTaxType extends BaseTaxType
class AdminProfileController extends BaseAdminController
{
public function pricePercentRetriever()
public function defaultAction()
{
if (null !== $response = $this->checkAuth("admin.admin-profile.view")) return $response;
return $this->render("admin-profiles", array("display_admin_profile" => 20));
}
public function fixAmountRetriever(\Thelia\Model\Product $product)
{
}
public function getRequirementsList()
{
return array(
'featureId' => new ModelValidIdType('Feature'),
'slices' => new FloatToFloatArrayType(),
);
}
public function getTitle()
{
return "% slice Tax depending on a feature";
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program 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 */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
/**
* Class LanguageController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class LanguageController extends BaseAdminController
{
public function defaultAction()
{
if (null !== $response = $this->checkAuth("admin.configuration.languages.view")) return $response;
return $this->render("languages");
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program 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 */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
/**
* Class MailingSystemController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class MailingSystemController extends BaseAdminController
{
public function defaultAction()
{
if (null !== $response = $this->checkAuth("admin.configuration.mailing-system.view")) return $response;
return $this->render("mailing-system");
}
}

View File

@@ -68,6 +68,7 @@ class TaxController extends AbstractCrudController
$event->setTitle($formData['title']);
$event->setDescription($formData['description']);
$event->setType($formData['type']);
$event->setRequirements($this->getRequirements($formData['type'], $formData));
return $event;
}
@@ -76,16 +77,12 @@ class TaxController extends AbstractCrudController
{
$event = new TaxEvent();
/* check the requirements */
if(!$this->checkRequirements($formData)) {
}
$event->setLocale($formData['locale']);
$event->setId($formData['id']);
$event->setTitle($formData['title']);
$event->setDescription($formData['description']);
$event->setType($formData['type']);
$event->setRequirements($this->getRequirements($formData['type'], $formData));
return $event;
}
@@ -207,4 +204,24 @@ class TaxController extends AbstractCrudController
}
protected function getRequirements($type, $formData)
{
$requirements = array();
foreach($formData as $data => $value) {
if(!strstr($data, ':')) {
continue;
}
$couple = explode(':', $data);
if(count($couple) != 2 || $couple[0] != $type) {
continue;
}
$requirements[$couple[1]] = $value;
}
return $requirements;
}
}

View File

@@ -236,6 +236,23 @@ class TaxRuleController extends AbstractCrudController
return parent::updateAction();
}
public function setDefaultAction()
{
if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response;
$setDefaultEvent = new TaxRuleEvent();
$taxRuleId = $this->getRequest()->attributes->get('tax_rule_id');
$setDefaultEvent->setId(
$taxRuleId
);
$this->dispatch(TheliaEvents::TAX_RULE_SET_DEFAULT, $setDefaultEvent);
$this->redirectToListTemplate();
}
public function processUpdateTaxesAction()
{
// Check current user authorization

View File

@@ -31,10 +31,11 @@ use Thelia\Core\Security\Exception\UsernameNotFoundException;
use Thelia\Form\CustomerCreation;
use Thelia\Form\CustomerLogin;
use Thelia\Form\CustomerLostPasswordForm;
use Thelia\Form\CustomerModification;
use Thelia\Form\CustomerUpdateForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\Customer;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\CustomerQuery;
use Thelia\Tools\URL;
use Thelia\Log\Tlog;
use Thelia\Core\Security\Exception\WrongPasswordException;
@@ -128,32 +129,56 @@ class CustomerController extends BaseFrontController
}
}
protected function getExistingCustomer($customer_id)
{
return CustomerQuery::create()
->findOneById($customer_id);
}
/**
* Update customer data. On success, redirect to success_url if exists.
* Otherwise, display the same view again.
*/
public function viewAction()
{
$this->checkAuth();
$customer = $this->getSecurityContext()->getCustomerUser();
$data = array(
'id' => $customer->getId(),
'title' => $customer->getTitleId(),
'firstname' => $customer->getFirstName(),
'lastname' => $customer->getLastName(),
'email' => $customer->getEmail(),
);
$customerUpdateForm = new CustomerUpdateForm($this->getRequest(), 'form', $data);
// Pass it to the parser
$this->getParserContext()->addForm($customerUpdateForm);
}
public function updateAction()
{
if ($this->getSecurityContext()->hasCustomerUser()) {
$message = false;
$customerModification = new CustomerModification($this->getRequest());
$customerUpdateForm = new CustomerUpdateForm($this->getRequest());
try {
$customer = $this->getSecurityContext()->getCustomerUser();
$form = $this->validateForm($customerModification, "post");
$form = $this->validateForm($customerUpdateForm, "post");
$customerChangeEvent = $this->createEventInstance($form->getData());
$customerChangeEvent->setCustomer($customer);
$this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent);
$this->processLogin($customerChangeEvent->getCustomer());
$this->redirectSuccess($customerModification);
$this->redirectSuccess($customerUpdateForm);
} catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
@@ -164,10 +189,10 @@ class CustomerController extends BaseFrontController
if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer modification process : %s.", $message));
$customerModification->setErrorMessage($message);
$customerUpdateForm->setErrorMessage($message);
$this->getParserContext()
->addForm($customerModification)
->addForm($customerUpdateForm)
->setGeneralError($message)
;
}
@@ -193,6 +218,13 @@ class CustomerController extends BaseFrontController
$form = $this->validateForm($customerLoginForm, "post");
// If User is a new customer
if ($form->get('account')->getData() == 0 && !$form->get("email")->getErrors()) {
$this->redirectToRoute("customer.create.view", array("email" => $form->get("email")->getData()));
} else {
try {
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
$customer = $authenticator->getAuthentifiedUser();
@@ -201,23 +233,18 @@ class CustomerController extends BaseFrontController
$this->redirectSuccess($customerLoginForm);
} catch (FormValidationException $e) {
if ($request->request->has("account")) {
$account = $request->request->get("account");
$form = $customerLoginForm->getForm();
if ($account == 0 && $form->get("email")->getData() !== null) {
$this->redirectToRoute("customer.create.view", array("email" => $form->get("email")->getData()));
}
}
$message = sprintf("Please check your input: %s", $e->getMessage());
} catch (UsernameNotFoundException $e) {
$message = "Wrong email or password. Please try again";
} catch (WrongPasswordException $e) {
$message = "Wrong email or password. Please try again";
} catch (AuthenticationException $e) {
$message = "Wrong email or password. Please try again";
}
}
} catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
} catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage());
}
@@ -265,14 +292,14 @@ class CustomerController extends BaseFrontController
$data["title"],
$data["firstname"],
$data["lastname"],
$data["address1"],
$data["address2"],
$data["address3"],
$data["phone"],
$data["cellphone"],
$data["zipcode"],
$data["city"],
$data["country"],
isset($data["address1"])?$data["address1"]:null,
isset($data["address2"])?$data["address2"]:null,
isset($data["address3"])?$data["address3"]:null,
isset($data["phone"])?$data["phone"]:null,
isset($data["cellphone"])?$data["cellphone"]:null,
isset($data["zipcode"])?$data["zipcode"]:null,
isset($data["city"])?$data["city"]:null,
isset($data["country"])?$data["country"]:null,
isset($data["email"])?$data["email"]:null,
isset($data["password"]) ? $data["password"]:null,
$this->getRequest()->getSession()->getLang()->getId(),

View File

@@ -34,6 +34,7 @@ class TaxEvent extends ActionEvent
protected $title;
protected $description;
protected $type;
protected $requirements;
public function __construct(Tax $tax = null)
{
@@ -106,4 +107,14 @@ class TaxEvent extends ActionEvent
{
return $this->type;
}
public function setRequirements($requirements)
{
$this->requirements = $requirements;
}
public function getRequirements()
{
return $this->requirements;
}
}

View File

@@ -11,13 +11,13 @@ class TheliaType extends AbstractType
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'instance' => false,
//'instance' => false,
'type' => false,
'options' => false,
));
$resolver->setAllowedTypes(array(
'instance' => array('Thelia\Type\TypeInterface'),
//'instance' => array('Thelia\Type\TypeInterface'),
));
$resolver->setAllowedValues(array(
@@ -31,7 +31,7 @@ class TheliaType extends AbstractType
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars = array_replace($view->vars, array(
'instance' => $options['instance'],
//'instance' => $options['instance'],
'type' => $options['type'],
'options' => $options['options'],
));

View File

@@ -102,6 +102,7 @@ class Cart extends BaseLoop
->set("TAXED_PRICE", $cartItem->getTaxedPrice($taxCountry))
->set("PROMO_TAXED_PRICE", $cartItem->getTaxedPromoPrice($taxCountry))
->set("IS_PROMO", $cartItem->getPromo() === 1 ? 1 : 0);
$loopResultRow->set("PRODUCT_SALE_ELEMENTS_ID", $productSaleElement->getId());
$result->addRow($loopResultRow);
}

View File

@@ -86,6 +86,7 @@ class Content extends BaseI18nLoop
*/
public function exec(&$pagination)
{
$search = ContentQuery::create();
/* manage translations */
@@ -138,27 +139,15 @@ class Content extends BaseI18nLoop
$current_folder = $this->getCurrent_folder();
if ($current_folder === true) {
$search->filterByFolder(
FolderQuery::create()->filterByContent(
ContentFolderQuery::create()->filterByContentId(
$this->request->get("content_id"),
Criteria::EQUAL
)->find(),
Criteria::IN
)->find(),
Criteria::IN
);
$current = ContentQuery::create()->findPk($this->request->get("content_id"));
$search->filterByFolder($current->getFolders(), Criteria::IN);
} elseif ($current_folder === false) {
$search->filterByFolder(
FolderQuery::create()->filterByContent(
ContentFolderQuery::create()->filterByContentId(
$this->request->get("content_id"),
Criteria::EQUAL
)->find(),
Criteria::IN
)->find(),
Criteria::NOT_IN
);
$current = ContentQuery::create()->findPk($this->request->get("content_id"));
$search->filterByFolder($current->getFolders(), Criteria::NOT_IN);
}
$visible = $this->getVisible();

View File

@@ -87,6 +87,7 @@ class Product extends BaseI18nLoop
Argument::createIntTypeArgument('depth', 1),
Argument::createBooleanOrBothTypeArgument('visible', 1),
Argument::createIntTypeArgument('currency'),
Argument::createAnyTypeArgument('title'),
new Argument(
'order',
new TypeCollection(
@@ -171,6 +172,17 @@ class Product extends BaseI18nLoop
$search->filterByRef($ref, Criteria::IN);
}
$title = $this->getTitle();
if(!is_null($title)){
$search->where(" CASE WHEN NOT ISNULL(`requested_locale_i18n`.ID) THEN `requested_locale_i18n`.`TITLE` ELSE `default_locale_i18n`.`TITLE` END ".Criteria::LIKE." ?", "%".$title."%", \PDO::PARAM_STR);
}
$category = $this->getCategory();
$categoryDefault = $this->getCategoryDefault();
@@ -461,7 +473,7 @@ class Product extends BaseI18nLoop
$visible = $this->getVisible();
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0);
if ($visible !== BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0);
$exclude = $this->getExclude();

View File

@@ -151,12 +151,10 @@ class Tax extends BaseI18nLoop
$loopResultRow = new LoopResultRow($loopResult, $tax, $this->versionable, $this->timestampable, $this->countable);
$requirements = json_decode( base64_decode( $tax->getSerializedRequirements() ), true );
$loopResultRow
->set("ID" , $tax->getId())
->set("TYPE" , $tax->getType())
->set("REQUIREMENTS" , $requirements)
->set("REQUIREMENTS" , $tax->getRequirements())
->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $locale)
->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE'))

View File

@@ -124,12 +124,8 @@ class Form extends AbstractSmartyPlugin
$template->assign("value", $fieldValue);
$template->assign("options", $formFieldView->vars);
$template->assign("checked", isset($fieldVars['checked']) ? $fieldVars['checked'] : false);
// If Checkbox input type
if ($fieldVars['checked'] !== null) {
$this->renderFormFieldCheckBox($template, $formFieldView['checked']);
}
//data
$template->assign("data", $fieldVars['data']);
@@ -137,6 +133,8 @@ class Form extends AbstractSmartyPlugin
$template->assign("label", $fieldVars["label"]);
$template->assign("label_attr", $fieldVars["label_attr"]);
$template->assign('required', isset($fieldVars['required']) ? $fieldVars['required'] : false);
$errors = $fieldVars["errors"];
$template->assign("error", empty($errors) ? false : true);
@@ -177,6 +175,7 @@ class Form extends AbstractSmartyPlugin
if($formFieldType instanceof TheliaType) {
$template->assign("formType", $formFieldView->vars['type']);
switch($formFieldView->vars['type']) {
case "choice":
if(!isset($formFieldView->vars['options']['choices']) || !is_array($formFieldView->vars['options']['choices'])) {
@@ -429,17 +428,4 @@ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVar
new SmartyPluginDescriptor("block", "form_error", $this, "formError")
);
}
/**
* @param \Smarty_Internal_Template $template
* @param $formFieldView
*/
public function renderFormFieldCheckBox(\Smarty_Internal_Template $template, $isChecked)
{
$template->assign("value", 0);
if ($isChecked) {
$template->assign("value", 1);
}
$template->assign("value", $isChecked);
}
}

View File

@@ -0,0 +1,65 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program 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 */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class AdminProfileCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("wording" , "text" , array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Wording *"),
"label_attr" => array(
"for" => "wording"
))
)
->add("name" , "text" , array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Name *"),
"label_attr" => array(
"for" => "name"
))
)
->add("description" , "text" , array(
"label" => Translator::getInstance()->trans("Description"),
"label_attr" => array(
"for" => "description"
))
)
;
}
public function getName()
{
return "thelia_admin_profile_creation";
}
}

View File

@@ -40,6 +40,16 @@ class CustomerCreation extends BaseForm
{
$this->formBuilder
->add("auto_login", "integer")
// Personal Informations
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Title"),
"label_attr" => array(
"for" => "title"
)
))
->add("firstname", "text", array(
"constraints" => array(
new Constraints\NotBlank()
@@ -58,84 +68,6 @@ class CustomerCreation extends BaseForm
"for" => "lastname"
)
))
->add("address1", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label_attr" => array(
"for" => "address"
),
"label" => Translator::getInstance()->trans("Street Address"),
"label_attr" => array(
"for" => "address1"
)
))
->add("address2", "text", array(
"label" => Translator::getInstance()->trans("Address Line 2"),
"label_attr" => array(
"for" => "address2"
)
))
->add("address3", "text", array(
"label" => Translator::getInstance()->trans("Address Line 3"),
"label_attr" => array(
"for" => "address3"
)
))
->add("company", "text", array(
"label" => Translator::getInstance()->trans("Company Name"),
"label_attr" => array(
"for" => "company"
)
))
->add("phone", "text", array(
"label" => Translator::getInstance()->trans("Phone"),
"label_attr" => array(
"for" => "phone"
)
))
->add("cellphone", "text", array(
"label" => Translator::getInstance()->trans("Cellphone"),
"label_attr" => array(
"for" => "cellphone"
)
))
->add("zipcode", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Zip code"),
"label_attr" => array(
"for" => "zipcode"
)
))
->add("city", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("City"),
"label_attr" => array(
"for" => "city"
)
))
->add("country", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Country"),
"label_attr" => array(
"for" => "country"
)
))
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Title"),
"label_attr" => array(
"for" => "title"
)
))
->add("email", "email", array(
"constraints" => array(
new Constraints\NotBlank(),
@@ -163,6 +95,79 @@ class CustomerCreation extends BaseForm
),
"label" => "email confirmation"
))*/
->add("phone", "text", array(
"label" => Translator::getInstance()->trans("Phone"),
"label_attr" => array(
"for" => "phone"
),
"required" => false
))
->add("cellphone", "text", array(
"label" => Translator::getInstance()->trans("Cellphone"),
"label_attr" => array(
"for" => "cellphone"
),
"required" => false
))
// Delivery Informations
->add("company", "text", array(
"label" => Translator::getInstance()->trans("Company Name"),
"label_attr" => array(
"for" => "company"
),
"required" => false
))
->add("address1", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Street Address"),
"label_attr" => array(
"for" => "address1"
)
))
->add("address2", "text", array(
"label" => Translator::getInstance()->trans("Address Line 2"),
"label_attr" => array(
"for" => "address2"
),
"required" => false
))
->add("address3", "text", array(
"label" => Translator::getInstance()->trans("Address Line 3"),
"label_attr" => array(
"for" => "address3"
),
"required" => false
))
->add("city", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("City"),
"label_attr" => array(
"for" => "city"
)
))
->add("zipcode", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Zip code"),
"label_attr" => array(
"for" => "zipcode"
)
))
->add("country", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Country"),
"label_attr" => array(
"for" => "country"
)
))
// Login Information
->add("password", "password", array(
"constraints" => array(
new Constraints\NotBlank(),
@@ -186,8 +191,14 @@ class CustomerCreation extends BaseForm
"for" => "password_confirmation"
)
))
;
->add("agreed", "checkbox", array(
"constraints" => array(
new Constraints\True(array("message" => "Please accept the Terms and conditions in order to register."))
),
"label_attr" => array(
"for" => "agreed"
)
));
}
public function verifyPasswordField($value, ExecutionContextInterface $context)

View File

@@ -22,10 +22,19 @@
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ExecutionContextInterface;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Base\CustomerQuery;
/**
* Class CustomerLogin
* @package Thelia\Form
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerLogin extends BaseForm
{
protected function buildForm()
@@ -33,27 +42,82 @@ class CustomerLogin extends BaseForm
$this->formBuilder
->add("email", "email", array(
"constraints" => array(
new NotBlank(),
new Email()
new Constraints\NotBlank(),
new Constraints\Email(),
new Constraints\Callback(array(
"methods" => array(
array($this, "verifyExistingEmail")
)
))
),
"label" => Translator::getInstance()->trans("Please enter your email address"),
"label_attr" => array(
"for" => "email"
)
))
->add("account", "choice", array(
"constraints" => array(
new Constraints\Callback(array(
"methods" => array(
array($this, "verifyAccount")
)
))
),
"required" => true
"choices" => array(
0 => Translator::getInstance()->trans("No, I am a new customer."),
1 => Translator::getInstance()->trans("Yes, I have a password :")
),
"label_attr" => array(
"for" => "account"
),
"data" => 0
))
->add("password", "password", array(
"constraints" => array(
new NotBlank()
),
/*"constraints" => array(
new Constraints\NotBlank()
),*/
"label" => Translator::getInstance()->trans("Please enter your password"),
"label_attr" => array(
"for" => "password"
),
"required" => true
))
->add("remember_me", "checkbox")
;
"required" => false
));
}
/**
* If the user select "Yes, I have a password", we check the password.
*/
public function verifyAccount($value, ExecutionContextInterface $context)
{
if ($value == 1) {
$data = $context->getRoot()->getData();
if (false === $data['password'] || (empty($data['password']) && '0' != $data['password'])) {
$context->getViolations()->add(new ConstraintViolation(
'This value should not be blank.',
'account_password',
array(),
$context->getRoot(),
'children[password].data',
'propertyPath'
));
}
}
}
/**
* If the user select "I'am a new customer", we make sure is email address does not exit in the database.
*/
public function verifyExistingEmail($value, ExecutionContextInterface $context)
{
$data = $context->getRoot()->getData();
if ($data["account"] == 0) {
$customer = CustomerQuery::create()->findOneByEmail($value);
if ($customer) {
$context->addViolation("A user already exists with this email address. Please login or if you've forgotten your password, go to Reset Your Password.");
}
}
}
public function getName()

View File

@@ -82,7 +82,7 @@ class CustomerLostPasswordForm extends BaseForm
{
$customer = CustomerQuery::create()->findOneByEmail($value);
if (null === $customer) {
$context->addViolation("This email does not exists exists");
$context->addViolation("This email does not exists");
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program 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 */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Translation\Translator;
/**
* Class CustomerUpdateForm
* @package Thelia\Form
* @author Christophe Laffont <claffont@openstudio.fr>
*/
class CustomerUpdateForm extends CustomerCreation
{
protected function buildForm()
{
parent::buildForm();
$this->formBuilder
->remove("auto_login")
// Remove From Personal Informations
->remove("phone")
->remove("cellphone")
// Remove Delivery Informations
->remove("company")
->remove("address1")
->remove("address2")
->remove("address3")
->remove("city")
->remove("zipcode")
->remove("country")
// Remove Login Information
->remove("password")
->remove("password_confirm")
// Remove Terms & conditions
->remove("agreed")
// Add Newsletter
->add("newsletter", "checkbox", array(
"label" => "I would like to receive the newsletter our the latest news.",
"label_attr" => array(
"for" => "newsletter"
),
"required" => false
));
}
public function getName()
{
return "thelia_customer_update";
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program 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 */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class LanguageCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("title", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Language title *"),
"label_attr" => array(
"for" => "title"
)
))
->add("isocode", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("ISO Code *"),
"label_attr" => array(
"for" => "isocode"
)
))
;
}
public function getName()
{
return "thelia_language_creation";
}
}

View File

@@ -64,8 +64,8 @@ class TaxCreationForm extends BaseForm
foreach($requirementList as $type => $requirements) {
foreach($requirements as $name => $requirementType) {
$this->formBuilder
->add($type . '_' . $name, new TheliaType(), array(
"instance" => $requirementType,
->add($type . ':' . $name, new TheliaType(), array(
//"instance" => $requirementType,
"constraints" => array(
new Constraints\Callback(
array(
@@ -77,8 +77,6 @@ class TaxCreationForm extends BaseForm
),
"attr" => array(
"tag" => "requirements",
),
"data" => array(
"tax_type" => $type,
),
"label" => Translator::getInstance()->trans($name),
@@ -96,11 +94,4 @@ class TaxCreationForm extends BaseForm
{
return "thelia_tax_creation";
}
public function verifyForm($value, ExecutionContextInterface $context)
{
$in = true;
//$this->getForm()->getChildren()
}
}

View File

@@ -36,7 +36,11 @@ trait ModelEventDispatcherTrait {
*/
protected $dispatcher = null;
/**
* @param EventDispatcherInterface $dispatcher
*
* @return $this
*/
public function setDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;

View File

@@ -59,7 +59,7 @@ class RewritingResolver
public function load($rewrittenUrl)
{
$rewrittenUrl = ltrim($rewrittenUrl, '/');
$rewrittenUrl = urldecode($rewrittenUrl);
$this->search = $this->rewritingUrlQuery->getResolverSearch($rewrittenUrl);
if($this->search->count() == 0) {

View File

@@ -40,7 +40,7 @@ abstract class BaseType implements TypeInterface
public function verifyForm($value, ExecutionContextInterface $context)
{
if( ! $this->isValid($value) ) {
$context->addViolation("Thelia Type not matched");
$context->addViolation(sprintf("received value `%s` does not match `%s` type", $value, $this->getType()));
}
}
}

View File

@@ -45,13 +45,17 @@ class DebugBarListeners extends BaseAction implements EventSubscriberInterface {
{
$debugBar = $this->container->get("debugBar");
$alternativelogger = null;
if($this->container->getParameter('kernel.debug')) {
$alternativelogger = \Thelia\Log\Tlog::getInstance();
}
$debugBar->addCollector(new PhpInfoCollector());
//$debugBar->addCollector(new MessagesCollector());
//$debugBar->addCollector(new RequestDataCollector());
$debugBar->addCollector(new TimeDataCollector());
$debugBar->addCollector(new MemoryCollector());
$debugBar->addCollector(new PropelCollector(\Thelia\Log\Tlog::getInstance()));
$debugBar->addCollector(new PropelCollector($alternativelogger));
}
/**

View File

@@ -0,0 +1,219 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Admin profiles'}{/block}
{block name="check-permissions"}admin.admin-profiles.view{/block}
{block name="main-content"}
<div class="admin-profiles">
<div id="wrapper" class="container">
<div class="clearfix">
<ul class="breadcrumb pull-left">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/admin_profiles'}">{intl l="Admin profiles"}</a></li>
</ul>
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.admin-profiles.create"}
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new admin profile'}" href="#creation_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus"></span>
</a>
{/loop}
</div>
{module_include location='admin_profiles_top'}
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="table-responsive">
<form action="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="Profile"}
</caption>
<tbody>
<tr>
<td><label for="" class="label-control">{intl l="Profile"}</label></td>
<td>
<select name="" id="" data-toggle="selectpicker">
<option value="">1</option>
<option value="">2</option>
<option value="">3</option>
</select>
</td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Wording"}</label></td>
<td><input type="text" class="form-control" name="" value="gestionnairecommande" readonly></td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Name"}</label></td>
<td><input type="text" class="form-control" name="" value=""></td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Description"}</label></td>
<td><textarea type="text" class="form-control" name=""></textarea></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<div class="btn-group pull-right">
<button type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
<button class="btn btn-default"><span class="glyphicon glyphicon-trash"></span> {intl l="Delete"}</button>
</div>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="table-responsive">
<form action="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="General rights"}
</caption>
<thead>
<tr>
<th>{intl l="Authorization"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Access"}</th>
</tr>
</thead>
<tbody>
<tr>
<td>Access to customers</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" checked>
</div>
</td>
</tr>
<tr>
<td>Access to orders</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox">
</div>
</td>
</tr>
<tr>
<td>Access to catalog</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox">
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">
<button type="submit" class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
</div>
{module_include location='admin_profiles_bottom'}
</div>
</div>
{* Creation dialog *}
{form name="thelia.admin.admin-profile.creation"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "creation_dialog"}
{form_hidden_fields form=$form}
{* Be sure to get the language_id, even if the form could not be validated *}
<input type="hidden" name="language_id" value="{$language_id}" />
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/configuration/admin_profile/update' admin_profile_id='_ID_'}" />
{/form_field}
{form_field form=$form field='wording'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Wording'}">
</div>
{/form_field}
{form_field form=$form field='name'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Name'}">
</div>
{/form_field}
{form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<textarea id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Description'}"></textarea>
</div>
{/form_field}
{module_include location='admin_profile_create_form'}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "creation_dialog"
dialog_title = {intl l="Create a new admin profile"}
dialog_body = {$smarty.capture.creation_dialog nofilter}
dialog_ok_label = {intl l="Create this admin profile"}
form_action = {url path='/admin/configuration/admin_profile/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/main.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -17,6 +17,9 @@
}
}
.navbar-nav > li:hover{
background-color: @active-menu;
}
}
// Inner for background effects

View File

@@ -13,6 +13,9 @@
@brand-primary: #f39922;
// Nav
// -------------------------
@active-menu: #eeeeee;
// Links
// -------------------------

View File

@@ -5,7 +5,7 @@
{block name="check-permissions"}admin.configuration.view{/block}
{block name="main-content"}
<div class="configuration">
<div class="configuration">
<div id="wrapper" class="container">
@@ -180,5 +180,5 @@
{module_include location='configuration_bottom'}
</div>
</div>
</div>
</div>
{/block}

View File

@@ -0,0 +1,272 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Thelia Languages'}{/block}
{block name="check-permissions"}admin.configuration.languages.view{/block}
{block name="main-content"}
<div class="languages">
<div id="wrapper" class="container">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/languages'}">{intl l="Languages"}</a></li>
</ul>
{module_include location='languages_top'}
<div class="row">
<div class="col-md-6">
<div class="general-block-decorator">
<form action="" method="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="Languages management"}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.languages.create"}
<a class="btn btn-default btn-primary action-btn" title="{intl l='Add a new language'}" href="#creation_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus-sign"></span>
</a>
{/loop}
</caption>
<thead>
<tr>
<th>{intl l="Language name"}</th>
<th>{intl l="ISO 639 Code"}</th>
<th>{intl l="Default"}</th>
<th>{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control" name="" value="France"></td>
<td><input type="text" class="form-control" name="" value="fr"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="" checked>
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
<tr>
<td><input type="text" class="form-control" name="" value="English"></td>
<td><input type="text" class="form-control" name="" value="en"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="">
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
<tr>
<td><input type="text" class="form-control" name="" value="Spanish"></td>
<td><input type="text" class="form-control" name="" value="es"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="">
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button type="submit" class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
<div class="col-md-6">
<div class="general-block-decorator">
<div class="title title-without-tabs">{intl l="Parameters"}</div>
<form action="" method="post">
<div class="form-group">
<label for="" class="label-control">{intl l="If a translation is missing or incomplete :"}</label>
<div class="input-group">
<select name="" id="" data-toggle="selectpicker">
<option value="">Replace by the default language</option>
<option value="">Strictly use the requested language</option>
</select>
<div class="input-group-btn">
<button type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span></button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator clearfix">
<div class="title title-without-tabs">{intl l="Association language/URL"}</div>
<form action="" method="post">
<div class="col-md-6">
<div class="form-group">
<label for="" class="label-control"><input type="radio" name="" checked> {intl l="Using a same domain for all languages"}</label>
<input type="url" class="form-control" name="" placeholder="http://www.domain.com">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="" class="label-control"><input type="radio" name=""> {intl l="Using a domain or subdomain for each language"}</label>
</div>
<table class="table table-striped table-condensed table-left-aligned">
<tbody>
<tr>
<th>{intl l="France"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
<tr>
<th>{intl l="English"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
<tr>
<th>{intl l="Spanish"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<button type="submit" disabled class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</div>
</form>
</div>
</div>
</div>
{module_include location='languages_bottom'}
</div>
</div>
{form name="thelia.admin.language.creation"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "creation_dialog"}
{form_hidden_fields form=$form}
{* Be sure to get the language_id, even if the form could not be validated *}
<input type="hidden" name="language_id" value="{$language_id}" />
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/configuration/languages/update' language_id='_ID_'}" />
{/form_field}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Language title'}">
</div>
{/form_field}
{form_field form=$form field='isocode'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='ISO Code'}">
</div>
{/form_field}
{module_include location='language_create_form'}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "creation_dialog"
dialog_title = {intl l="Create a new language"}
dialog_body = {$smarty.capture.creation_dialog nofilter}
dialog_ok_label = {intl l="Create this language"}
form_action = {url path='/admin/configuration/languages/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}
{* Delete confirmation dialog *}
{capture "delete_dialog"}
<input type="hidden" name="message_id" id="language_delete_id" value="" />
{module_include location='languages_delete_form'}
{/capture}
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "delete_dialog"
dialog_title = {intl l="Delete language"}
dialog_message = {intl l="Do you really want to delete this language ?"}
form_action = {url path='/admin/configuration/languages/delete'}
form_content = {$smarty.capture.delete_dialog nofilter}
}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
<script>
// Toogle switch on input radio
$('.switch-radio').on('switch-change', function () {
$('.switch-radio').bootstrapSwitch('toggleRadioState');
});
</script>
{/javascripts}
{javascripts file='assets/js/main.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -0,0 +1,102 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Thelia Mailing System'}{/block}
{block name="check-permissions"}admin.configuration.mailing-system.view{/block}
{block name="main-content"}
<div class="mailing-system">
<div id="wrapper" class="container">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/mailing_system'}">{intl l="Mailing system"}</a></li>
</ul>
{module_include location='mailing_system_top'}
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="title title-without-tabs">{intl l="Configuration variables"}</div>
<form action="" method="">
<div class="form-group">
<label for="" class="label-control">{intl l="SMTP Server"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="SMTP Server"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Port"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="port"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Username"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="username"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Password"}</label>
<div class="input-group">
<input type="password" class="form-control" name="" placeholder="{intl l="password"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Protocol"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="protocol"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Active ?"}</label>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" name="" id="" checked>
</div>
</div>
</form>
</div>
</div>
</div>
{module_include location='mailing_system_bottom'}
</div>
</div>
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -54,7 +54,7 @@
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div>
{/form_field}
@@ -65,7 +65,7 @@
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
@@ -78,27 +78,29 @@
<div class="form-group">
<select name="{$name}" class="js-change-tax-type" data-toggle="selectpicker">
{foreach $choices as $choice}
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option>
<option value="{$choice->value}" {if !$form_error && $choice->value == $TYPE || $form_error && $choice->value == $value}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
</div>
</div>
{$typeValue = $value}
{/form_field}
{form_tagged_fields form=$form tag='requirements'}
<div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$data.tax_type}" {if $data.tax_type != $TYPE}style="display: none"{/if}>
<div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$attr_list.tax_type}" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}style="display: none"{/if}>
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} : {$formType}
{intl l=$label}
</label>
{if $formType == 'choice'}
<select name="{$name}">
<select name="{$name}" data-toggle="selectpicker" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}disabled="disabled"{/if}>
{foreach $choices as $choice}
<option value="{$choice->value}" {if $REQUIREMENTS.$label == $choice->value}selected="selected" {/if}>{$choice->label}</option>
<option value="{$choice->value}" {if !$form_error && $REQUIREMENTS.$label == $choice->value || $form_error && $value == $choice->value}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
{/if}
{if $formType == 'text'}
<input type="text" name="{$name}" value="{$REQUIREMENTS.$label}">
<input type="text" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}disabled="disabled"{/if} id="{$label_attr.for}" name="{$name}" required="required" class="form-control" value="{if $form_error}{$value}{else}{$REQUIREMENTS.$label}{/if}">
{/if}
</div>
{/form_tagged_fields}
@@ -142,7 +144,10 @@
<script>
$(function() {
$('.js-change-tax-type').change(function(e){
$('.js-tax-requirements').children('select, input').attr('disabled', true);
$('.js-tax-requirements').hide();
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select, input').attr('disabled', false);
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select').selectpicker("refresh");
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').show();
});
});

View File

@@ -6,10 +6,10 @@
{block name="main-content"}
{assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}}
{assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}}
{assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}}
{assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}}
<div class="taxes-rules edit-taxes-rules">
<div class="taxes-rules edit-taxes-rules">
<div id="wrapper" class="container">
@@ -214,7 +214,7 @@
</div>
{* Confirmation dialog *}
{* Confirmation dialog *}
{form name="thelia.admin.taxrule.taxlistupdate"}
{if $form_error_message}
@@ -312,7 +312,7 @@
$('#' + selectId).selectpicker('deselectAll');
});
{literal}
{literal}
$('#country-selector').change(function(e) {
$('#country-selector-form').submit();
});
@@ -416,7 +416,7 @@
}
});
{/literal}
{/literal}
});

View File

@@ -5,7 +5,7 @@
{block name="check-permissions"}admin.taxes-rules.view{/block}
{block name="main-content"}
<div class="taxes-rules">
<div class="taxes-rules">
<div id="wrapper" class="container">
@@ -55,9 +55,9 @@
</caption>
<thead>
<tr>
<th>{intl l="Name"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Actions"}</th>
<th class="col-md-3">{intl l="Name"}</th>
<th class="col-md-5">{intl l="Description"}</th>
<th class="col-md-1">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
@@ -100,9 +100,10 @@
</caption>
<thead>
<tr>
<th>{intl l="Name"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Actions"}</th>
<th class="col-md-3">{intl l="Name"}</th>
<th class="col-md-4">{intl l="Description"}</th>
<th class="col-md-1">{intl l="Default"}</th>
<th class="col-md-1">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
@@ -112,13 +113,19 @@
<tr>
<td>{$TITLE}</td>
<td>{$DESCRIPTION}</td>
<td>
{if $IS_DEFAULT == 1}
<span class="glyphicon glyphicon-ok"></span>
{/if}
</td>
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"}
<a class="btn btn-default btn-xs" title="{intl l='Change this tax rule'}" href="{url path="/admin/configuration/taxes_rules/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
<a class="btn btn-default btn-xs" title="{intl l='Set as default tax rule'}" href="{url path="/admin/configuration/taxes_rules/update/set_default/$ID"}" {if $IS_DEFAULT == 1}disabled{/if}><span class="glyphicon glyphicon-star"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.dele"}
<a class="btn btn-default btn-xs js-delete-tax-rule" title="{intl l='Delete this tax rule'}" href="#tax_rule_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
@@ -137,19 +144,19 @@
{module_include location='taxes_rules_bottom'}
</div>
</div>
</div>
{* -- Add tax confirmation dialog ----------------------------------- *}
{form name="thelia.admin.tax.add"}
{form name="thelia.admin.tax.add"}
{if $form_error_message}
{if $form_error_message}
{$taxCreateError = true}
{else}
{else}
{$taxCreateError = false}
{/if}
{/if}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_create_dialog"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_create_dialog"}
{form_hidden_fields form=$form}
@@ -157,12 +164,10 @@
<input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div>
{/form_field}
@@ -173,7 +178,7 @@
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
@@ -184,16 +189,38 @@
</label>
<div class="form-group">
<select name="{$name}" data-toggle="selectpicker">
{foreach $choices as $choice}
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option>
<select name="{$name}" class="js-change-tax-type" data-toggle="selectpicker">
{$typeValueWithError = $value}
{foreach from=$choices key=key item=choice}
{if $key == 0}
{$typeValue = $choice->value}
{/if}
<option value="{$choice->value}" {if $form_error && $choice->value == $value || !$form_error && $key == 0}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
</div>
</div>
{/form_field}
{/capture}
{form_tagged_fields form=$form tag='requirements'}
<div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$attr_list.tax_type}" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}style="display: none"{/if}>
<label for="{$label_attr.for}" class="control-label">
{intl l=$label}
</label>
{if $formType == 'choice'}
<select name="{$name}" data-toggle="selectpicker" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}disabled="disabled"{/if}>
{foreach $choices as $choice}
<option value="{$choice->value}" {if !$form_error && $REQUIREMENTS.$label == $choice->value || $form_error && $value == $choice->value}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
{/if}
{if $formType == 'text'}
<input type="text" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}disabled="disabled"{/if} id="{$label_attr.for}" name="{$name}" required="required" class="form-control" value="{if $form_error}{$value}{else}{$REQUIREMENTS.$label}{/if}">
{/if}
</div>
{/form_tagged_fields}
{/capture}
{include
file = "includes/generic-create-dialog.html"
@@ -210,39 +237,39 @@
form_error_message = $form_error_message
}
{/form}
{/form}
{* -- Delete tax confirmation dialog ----------------------------------- *}
{capture "tax_delete_dialog"}
{capture "tax_delete_dialog"}
<input type="hidden" name="tax_id" id="tax_delete_id" value="" />
{module_include location='tax_delete_form'}
{/capture}
{/capture}
{include
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "tax_delete_dialog"
dialog_title = {intl l="Delete tax"}
dialog_message = {intl l="Do you really want to delete this tax ?"}
form_action = {url path='/admin/configuration/taxes/delete'}
form_content = {$smarty.capture.tax_delete_dialog nofilter}
form_action = {url path='/admin/configuration/taxes/delete'}
form_content = {$smarty.capture.tax_delete_dialog nofilter}
}
{* -- Add tax rule confirmation dialog ----------------------------------- *}
{form name="thelia.admin.taxrule.add"}
{form name="thelia.admin.taxrule.add"}
{if $form_error_message}
{if $form_error_message}
{$taxRuleCreateError = true}
{else}
{else}
{$taxRuleCreateError = false}
{/if}
{/if}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_rule_create_dialog"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_rule_create_dialog"}
{form_hidden_fields form=$form}
@@ -270,7 +297,7 @@
</div>
{/form_field}
{/capture}
{/capture}
{include
file = "includes/generic-create-dialog.html"
@@ -287,49 +314,50 @@
form_error_message = $form_error_message
}
{/form}
{/form}
{* -- Delete tax rule confirmation dialog ----------------------------------- *}
{capture "tax_rule_delete_dialog"}
{capture "tax_rule_delete_dialog"}
<input type="hidden" name="tax_rule_id" id="tax_rule_delete_id" value="" />
{module_include location='tax_rule_delete_form'}
{/capture}
{/capture}
{include
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "tax_rule_delete_dialog"
dialog_title = {intl l="Delete tax rule"}
dialog_message = {intl l="Do you really want to delete this tax rule ?"}
form_action = {url path='/admin/configuration/taxes_rules/delete'}
form_content = {$smarty.capture.tax_rule_delete_dialog nofilter}
form_action = {url path='/admin/configuration/taxes_rules/delete'}
form_content = {$smarty.capture.tax_rule_delete_dialog nofilter}
}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src='{$asset_url}'></script>
{/javascripts}
{/javascripts}
{javascripts file='assets/js/main.js'}
{javascripts file='assets/js/main.js'}
<script src='{$asset_url}'></script>
{/javascripts}
{/javascripts}
<script type="text/javascript">
<script type="text/javascript">
jQuery(function($) {
{if $taxRuleCreateError == true}
{if $taxRuleCreateError == true}
$('#tax_rule_create_dialog').modal();
{/if}
{/if}
{if $taxCreateError == true}
{if $taxCreateError == true}
$('#tax_create_dialog').modal();
{/if}
{/if}
$(".js-delete-tax-rule").click(function(e){
$('#tax_rule_delete_id').val($(this).data('id'))
@@ -338,6 +366,15 @@
$(".js-delete-tax").click(function(e){
$('#tax_delete_id').val($(this).data('id'))
});
</script>
$('.js-change-tax-type').change(function(e){
$('.js-tax-requirements').children('select, input').attr('disabled', true);
$('.js-tax-requirements').hide();
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select, input').attr('disabled', false);
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select').selectpicker("refresh");
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').show();
});
})
</script>
{/block}

View File

@@ -0,0 +1,131 @@
{extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-account-update{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [['title' => {intl l="Account"}, 'url'=>{url path="/account"}]]}
{$breadcrumbs = [
['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
['title' => {intl l="Update Profil"}, 'url'=>{url path="/account/update"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Update Profil"}</h1>
{form name="thelia.customer.update"}
{assign var="isPost" value="{$smarty.post|count}"}
<form id="form-register" class="form-horizontal" action="{url path="/account/update"}" method="post" role="form">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field}
{form_hidden_fields form=$form}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
<fieldset id="register-info" class="panel panel">
<div class="panel-heading">
{intl l="Personal Informations"}
</div>
<div class="panel-body">
{form_field form=$form field="title"}
<div class="form-group group-title {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
<option value="">-- {intl l="Select Title"} --</option>
{loop type="title" name="country.list"}
<option value="{$ID}" {if $value == $ID}selected{/if} >{$LONG}</option>
{/loop}
</select>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="firstname"}
<div class="form-group group-firstname {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="lastname"}
<div class="form-group group-lastname {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Doe" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" value="{$smarty.get.email|default:$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
</div>
</fieldset>
{form_field form=$form field="newsletter"}
<div class="form-group group-newsletter{if $error} has-error{/if}">
<div class="control-input">
<div class="checkbox">
<label class="control-label" for="{$label_attr.for}">
<input type="checkbox" name="{$name}" id="{$label_attr.for}" value="{$value}"{if $checked} checked{/if} {if $required} aria-required="true" required{/if}>{$label}
</label>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{/if}
</div>
</div>
</div><!--/.form-group-->
{/form_field}
<div class="form-group group-btn">
<div class="control-btn">
<button type="submit" class="btn btn-register">{intl l="Update"}</button>
</div>
</div><!--/.form-group-->
</form>
{/form}
</article>
</div><!-- /.layout -->
{/block}

View File

@@ -1,19 +1,18 @@
{extends file="layout.tpl"}
{block name="no-return-functions"}
{block name="no-return-functions" prepend}
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Account"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Account"}, 'url'=>{url path="/account"}]
]}
{/block}
{block name="body-class"}page-account{/block}
{block name="main-content"}
<div class="main">
@@ -40,13 +39,13 @@
<address class="adr">
<span class="street-address">{$ADDRESS1}</span><br>
{if $ADDRESS2 != ""}
<span class="street-address">{$ADDRESS2}</span><br>
<span class="extended-address">{$ADDRESS2}</span><br>
{/if}
{if $ADDRESS3 != ""}
<span class="street-address">{$ADDRESS3}</span><br>
<span class="extended-address">{$ADDRESS3}</span><br>
{/if}
<span class="postal-code">{$ZIPCODE}</span>
<span class="locality">{$CITY}, <span class="country-name">{loop type="country" name="customer.country.info" id=$COUNTRY}{$TITLE}{/loop}</span></span>
<span class="locality">{$CITY}<br><span class="country-name">{loop type="country" name="customer.country.info" id=$COUNTRY}{$TITLE}{/loop}</span></span>
</address>
</li>
<li>
@@ -56,11 +55,11 @@
{if $PHONE != ""}
<span class="tel">{$PHONE}</span>
{/if}
<span class="email"><a href="mailto:{$EMAIL}">{$EMAIL}</a></span>
<span class="email">{mailto address="{$EMAIL}" encode="hex"}</span>
</li>
<li class="group-btn">
<a href="#" class="btn btn-change-account"><i class="icon-pencil"></i> Change my account informations</a>
<a href="#" class="btn btn-change-password"><i class="icon-lock"></i> Change my password</a>
<a href="{url path="/account/update"}" class="btn btn-change-account"><i class="icon-pencil"></i> {intl l="Change my account informations"}</a>
<a href="{url path="/account/password"}" class="btn btn-change-password"><i class="icon-lock"></i> {intl l="Change my password"}</a>
</li>
</ul>
{/loop}
@@ -83,7 +82,7 @@
<tbody>
{loop type="address" name="customer.addresses" customer="current"}
<tr class="{if $DEFAULT == 1}address-primary{else}address-additional{/if}" id="customer-address-{$ID}">
<th>{$LABEL}</th>
<th>{$LABEL|default:"{intl l='Address %nb' nb={$LOOP_COUNT}}"}</th>
<td>
<ul class="list-address">
<li>
@@ -117,9 +116,9 @@
</td>
<td>
<div class="group-btn">
<a href="{url path="/address/update/{$ID}"}" class="btn btn-edit-address" data-toggle="tooltip" title="Edit this address"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a>
<a href="{url path="/address/update/{$ID}"}" class="btn btn-edit-address" data-toggle="tooltip" title="{intl l="Edit this address"}"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a>
{if $DEFAULT != 1}
<a href="{url path="/address/delete/{$ID}"}" class="btn btn-remove-address remove-address" title="{intl l="Remove this address"}" data-toggle="tooltip"><i class="icon-remove"></i> <span>{intl l="Cancel"}</span></a>
<a href="{url path="/address/delete/s{$ID}"}" class="btn btn-remove-address" data-toggle="popover" title="Do you really want to delete this address ?" data-content="And here's some amazing content. It's very engaging. right?" title="{intl l="Remove this address"}" ><i class="icon-remove"></i> <span>{intl l="Cancel"}</span></a>
{/if}
</div>
</td>
@@ -140,6 +139,7 @@
</div>
<div id="account-orders" class="panel-collapse collapse">
<div class="panel-body table-responsive">
{ifloop rel="customer.orders"}
<table class="table table-orders" summary="{intl l="List of orders"}">
<thead>
<tr>
@@ -163,9 +163,10 @@
</tbody>
</table>
{/ifloop}
{elseloop rel="customer.orders"}
<div class="orders-warning">
<strong>{intl l="Warning"}!</strong> {intl l="You don't have orders yet"}
<strong>{intl l="Warning"}!</strong> {intl l="You don't have orders yet."}
</div>
{/elseloop}
</div>
@@ -175,38 +176,6 @@
</article>
</div><!-- /.layout -->
<div class="modal fade" id="address-delete-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{intl l="Delete address"}</h3>
</div>
<div class="modal-body">
{intl l="Do you really want to delete this address ?"}
</div>
<div class="modal-footer">
<a href="#" type="button" class="btn btn-default" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove"></span> {intl l="No"}</a>
<a href="#" id="address-delete-link" type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span> {intl l="Yes"}</a>
</div>
</div>
</div>
</div>
{/block}
{block name="after-javascript-include"}
<script type="text/javascript">
$(document).ready(function(){
$(".remove-address").click(function(e){
e.preventDefault();
$("#address-delete-link").attr("href", $(this).attr("href"));
$('#address-delete-modal').modal('show');
})
})
</script>
{/block}
{block name="after-javascript-include"}{/block}

View File

@@ -4,15 +4,15 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">{intl l="Account"}</span></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Address"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-address{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
['title' => {intl l="Address Update"}, 'url'=>{url path="/address"}]
]}
{/block}
{block name="main-content"}
@@ -25,7 +25,7 @@
{loop name="customer.update" type="address" customer="current" id="{$address_id}"}
<form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post" role="form">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/customer/account"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on login success *}
{/form_field}
{form_field form=$form field='error_message'}

View File

@@ -4,15 +4,15 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">You are here: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">Home</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/customer/account"}" itemprop="url"><span itemprop="title">Account</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Address"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-address{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
['title' => {intl l="Address"}, 'url'=>{url path="/address"}]
]}
{/block}
{block name="main-content"}
@@ -24,7 +24,7 @@
{form name="thelia.address.create"}
<form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post" role="form">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/customer/account"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on login success *}
{/form_field}
{form_field form=$form field='error_message'}

View File

@@ -1,19 +0,0 @@
.magnify {
position: relative;
cursor: none
}
.magnify-large {
position: absolute;
display: none;
width: 175px;
height: 175px;
-webkit-box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
-moz-box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%
}

View File

@@ -1 +0,0 @@
.magnify{position:relative;cursor:none}.magnify-large{position:absolute;display:none;width:175px;height:175px;-webkit-box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);-moz-box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);-webkit-border-radius:100%;-moz-border-radius:100%;border-radius:100%}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,126 +0,0 @@
/* ========================================================================
* Bootstrap: affix.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#affix
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// AFFIX CLASS DEFINITION
// ======================
var Affix = function (element, options) {
this.options = $.extend({}, Affix.DEFAULTS, options)
this.$window = $(window)
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
this.$element = $(element)
this.affixed =
this.unpin = null
this.checkPosition()
}
Affix.RESET = 'affix affix-top affix-bottom'
Affix.DEFAULTS = {
offset: 0
}
Affix.prototype.checkPositionWithEventLoop = function () {
setTimeout($.proxy(this.checkPosition, this), 1)
}
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
var scrollTop = this.$window.scrollTop()
var position = this.$element.offset()
var offset = this.options.offset
var offsetTop = offset.top
var offsetBottom = offset.bottom
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
if (this.affixed === affix) return
if (this.unpin) this.$element.css('top', '')
this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))
if (affix == 'bottom') {
this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
}
}
// AFFIX PLUGIN DEFINITION
// =======================
var old = $.fn.affix
$.fn.affix = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.affix')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.affix.Constructor = Affix
// AFFIX NO CONFLICT
// =================
$.fn.affix.noConflict = function () {
$.fn.affix = old
return this
}
// AFFIX DATA-API
// ==============
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
var data = $spy.data()
data.offset = data.offset || {}
if (data.offsetBottom) data.offset.bottom = data.offsetBottom
if (data.offsetTop) data.offset.top = data.offsetTop
$spy.affix(data)
})
})
}(window.jQuery);

View File

@@ -1,98 +0,0 @@
/* ========================================================================
* Bootstrap: alert.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#alerts
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// ALERT CLASS DEFINITION
// ======================
var dismiss = '[data-dismiss="alert"]'
var Alert = function (el) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
var $this = $(this)
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
var $parent = $(selector)
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.hasClass('alert') ? $this : $this.parent()
}
$parent.trigger(e = $.Event('close.bs.alert'))
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
function removeElement() {
$parent.trigger('closed.bs.alert').remove()
}
$.support.transition && $parent.hasClass('fade') ?
$parent
.one($.support.transition.end, removeElement)
.emulateTransitionEnd(150) :
removeElement()
}
// ALERT PLUGIN DEFINITION
// =======================
var old = $.fn.alert
$.fn.alert = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.alert')
if (!data) $this.data('bs.alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
// ALERT NO CONFLICT
// =================
$.fn.alert.noConflict = function () {
$.fn.alert = old
return this
}
// ALERT DATA-API
// ==============
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
}(window.jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,109 +0,0 @@
/* ========================================================================
* Bootstrap: button.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#buttons
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// BUTTON PUBLIC CLASS DEFINITION
// ==============================
var Button = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Button.DEFAULTS, options)
}
Button.DEFAULTS = {
loadingText: 'loading...'
}
Button.prototype.setState = function (state) {
var d = 'disabled'
var $el = this.$element
var val = $el.is('input') ? 'val' : 'html'
var data = $el.data()
state = state + 'Text'
if (!data.resetText) $el.data('resetText', $el[val]())
$el[val](data[state] || this.options[state])
// push to event loop to allow forms to submit
setTimeout(function () {
state == 'loadingText' ?
$el.addClass(d).attr(d, d) :
$el.removeClass(d).removeAttr(d);
}, 0)
}
Button.prototype.toggle = function () {
var $parent = this.$element.closest('[data-toggle="buttons"]')
if ($parent.length) {
var $input = this.$element.find('input')
.prop('checked', !this.$element.hasClass('active'))
.trigger('change')
if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active')
}
this.$element.toggleClass('active')
}
// BUTTON PLUGIN DEFINITION
// ========================
var old = $.fn.button
$.fn.button = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.button')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.button', (data = new Button(this, options)))
if (option == 'toggle') data.toggle()
else if (option) data.setState(option)
})
}
$.fn.button.Constructor = Button
// BUTTON NO CONFLICT
// ==================
$.fn.button.noConflict = function () {
$.fn.button = old
return this
}
// BUTTON DATA-API
// ===============
$(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
e.preventDefault()
})
}(window.jQuery);

View File

@@ -1,217 +0,0 @@
/* ========================================================================
* Bootstrap: carousel.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#carousel
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// CAROUSEL CLASS DEFINITION
// =========================
var Carousel = function (element, options) {
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
this.sliding =
this.interval =
this.$active =
this.$items = null
this.options.pause == 'hover' && this.$element
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
Carousel.DEFAULTS = {
interval: 5000
, pause: 'hover'
, wrap: true
}
Carousel.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
Carousel.prototype.getActiveIndex = function () {
this.$active = this.$element.find('.item.active')
this.$items = this.$active.parent().children()
return this.$items.index(this.$active)
}
Carousel.prototype.to = function (pos) {
var that = this
var activeIndex = this.getActiveIndex()
if (pos > (this.$items.length - 1) || pos < 0) return
if (this.sliding) return this.$element.one('slid', function () { that.to(pos) })
if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
}
Carousel.prototype.pause = function (e) {
e || (this.paused = true)
if (this.$element.find('.next, .prev').length && $.support.transition.end) {
this.$element.trigger($.support.transition.end)
this.cycle(true)
}
this.interval = clearInterval(this.interval)
return this
}
Carousel.prototype.next = function () {
if (this.sliding) return
return this.slide('next')
}
Carousel.prototype.prev = function () {
if (this.sliding) return
return this.slide('prev')
}
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $next = next || $active[type]()
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last'
var that = this
if (!$next.length) {
if (!this.options.wrap) return
$next = this.$element.find('.item')[fallback]()
}
this.sliding = true
isCycling && this.pause()
var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
if ($next.hasClass('active')) return
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
this.$element.one('slid', function () {
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
$nextIndicator && $nextIndicator.addClass('active')
})
}
if ($.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
$active
.one($.support.transition.end, function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () { that.$element.trigger('slid') }, 0)
})
.emulateTransitionEnd(600)
} else {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger('slid')
}
isCycling && this.cycle()
return this
}
// CAROUSEL PLUGIN DEFINITION
// ==========================
var old = $.fn.carousel
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.carousel')
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
})
}
$.fn.carousel.Constructor = Carousel
// CAROUSEL NO CONFLICT
// ====================
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
return this
}
// CAROUSEL DATA-API
// =================
$(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var $this = $(this), href
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
var options = $.extend({}, $target.data(), $this.data())
var slideIndex = $this.attr('data-slide-to')
if (slideIndex) options.interval = false
$target.carousel(options)
if (slideIndex = $this.attr('data-slide-to')) {
$target.data('bs.carousel').to(slideIndex)
}
e.preventDefault()
})
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
var $carousel = $(this)
$carousel.carousel($carousel.data())
})
})
}(window.jQuery);

View File

@@ -1,179 +0,0 @@
/* ========================================================================
* Bootstrap: collapse.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#collapse
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// COLLAPSE PUBLIC CLASS DEFINITION
// ================================
var Collapse = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.transitioning = null
if (this.options.parent) this.$parent = $(this.options.parent)
if (this.options.toggle) this.toggle()
}
Collapse.DEFAULTS = {
toggle: true
}
Collapse.prototype.dimension = function () {
var hasWidth = this.$element.hasClass('width')
return hasWidth ? 'width' : 'height'
}
Collapse.prototype.show = function () {
if (this.transitioning || this.$element.hasClass('in')) return
var startEvent = $.Event('show.bs.collapse')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
var actives = this.$parent && this.$parent.find('> .panel > .in')
if (actives && actives.length) {
var hasData = actives.data('bs.collapse')
if (hasData && hasData.transitioning) return
actives.collapse('hide')
hasData || actives.data('bs.collapse', null)
}
var dimension = this.dimension()
this.$element
.removeClass('collapse')
.addClass('collapsing')
[dimension](0)
this.transitioning = 1
var complete = function () {
this.$element
.removeClass('collapsing')
.addClass('in')
[dimension]('auto')
this.transitioning = 0
this.$element.trigger('shown.bs.collapse')
}
if (!$.support.transition) return complete.call(this)
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
this.$element
.one($.support.transition.end, $.proxy(complete, this))
.emulateTransitionEnd(350)
[dimension](this.$element[0][scrollSize])
}
Collapse.prototype.hide = function () {
if (this.transitioning || !this.$element.hasClass('in')) return
var startEvent = $.Event('hide.bs.collapse')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
var dimension = this.dimension()
this.$element
[dimension](this.$element[dimension]())
[0].offsetHeight
this.$element
.addClass('collapsing')
.removeClass('collapse')
.removeClass('in')
this.transitioning = 1
var complete = function () {
this.transitioning = 0
this.$element
.trigger('hidden.bs.collapse')
.removeClass('collapsing')
.addClass('collapse')
}
if (!$.support.transition) return complete.call(this)
this.$element
[dimension](0)
.one($.support.transition.end, $.proxy(complete, this))
.emulateTransitionEnd(350)
}
Collapse.prototype.toggle = function () {
this[this.$element.hasClass('in') ? 'hide' : 'show']()
}
// COLLAPSE PLUGIN DEFINITION
// ==========================
var old = $.fn.collapse
$.fn.collapse = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.collapse')
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.collapse.Constructor = Collapse
// COLLAPSE NO CONFLICT
// ====================
$.fn.collapse.noConflict = function () {
$.fn.collapse = old
return this
}
// COLLAPSE DATA-API
// =================
$(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
var $this = $(this), href
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $target = $(target)
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $this.data()
var parent = $this.attr('data-parent')
var $parent = parent && $(parent)
if (!data || !data.transitioning) {
if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
}
$target.collapse(option)
})
}(window.jQuery);

View File

@@ -1,154 +0,0 @@
/* ========================================================================
* Bootstrap: dropdown.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#dropdowns
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// DROPDOWN CLASS DEFINITION
// =========================
var backdrop = '.dropdown-backdrop'
var toggle = '[data-toggle=dropdown]'
var Dropdown = function (element) {
var $el = $(element).on('click.bs.dropdown', this.toggle)
}
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
clearMenus()
if (!isActive) {
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
// if mobile we we use a backdrop because click events don't delegate
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
}
$parent.trigger(e = $.Event('show.bs.dropdown'))
if (e.isDefaultPrevented()) return
$parent
.toggleClass('open')
.trigger('shown.bs.dropdown')
$this.focus()
}
return false
}
Dropdown.prototype.keydown = function (e) {
if (!/(38|40|27)/.test(e.keyCode)) return
var $this = $(this)
e.preventDefault()
e.stopPropagation()
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
if (!isActive || (isActive && e.keyCode == 27)) {
if (e.which == 27) $parent.find(toggle).focus()
return $this.click()
}
var $items = $('[role=menu] li:not(.divider):visible a', $parent)
if (!$items.length) return
var index = $items.index($items.filter(':focus'))
if (e.keyCode == 38 && index > 0) index-- // up
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
if (!~index) index=0
$items.eq(index).focus()
}
function clearMenus() {
$(backdrop).remove()
$(toggle).each(function (e) {
var $parent = getParent($(this))
if (!$parent.hasClass('open')) return
$parent.trigger(e = $.Event('hide.bs.dropdown'))
if (e.isDefaultPrevented()) return
$parent.removeClass('open').trigger('hidden.bs.dropdown')
})
}
function getParent($this) {
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
var $parent = selector && $(selector)
return $parent && $parent.length ? $parent : $this.parent()
}
// DROPDOWN PLUGIN DEFINITION
// ==========================
var old = $.fn.dropdown
$.fn.dropdown = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('dropdown')
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.dropdown.Constructor = Dropdown
// DROPDOWN NO CONFLICT
// ====================
$.fn.dropdown.noConflict = function () {
$.fn.dropdown = old
return this
}
// APPLY TO STANDARD DROPDOWN ELEMENTS
// ===================================
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
}(window.jQuery);

View File

@@ -1,246 +0,0 @@
/* ========================================================================
* Bootstrap: modal.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#modals
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// MODAL CLASS DEFINITION
// ======================
var Modal = function (element, options) {
this.options = options
this.$element = $(element)
this.$backdrop =
this.isShown = null
if (this.options.remote) this.$element.load(this.options.remote)
}
Modal.DEFAULTS = {
backdrop: true
, keyboard: true
, show: true
}
Modal.prototype.toggle = function (_relatedTarget) {
return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
}
Modal.prototype.show = function (_relatedTarget) {
var that = this
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
this.$element.trigger(e)
if (this.isShown || e.isDefaultPrevented()) return
this.isShown = true
this.escape()
this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
this.backdrop(function () {
var transition = $.support.transition && that.$element.hasClass('fade')
if (!that.$element.parent().length) {
that.$element.appendTo(document.body) // don't move modals dom position
}
that.$element.show()
if (transition) {
that.$element[0].offsetWidth // force reflow
}
that.$element
.addClass('in')
.attr('aria-hidden', false)
that.enforceFocus()
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
transition ?
that.$element.find('.modal-dialog') // wait for modal to slide in
.one($.support.transition.end, function () {
that.$element.focus().trigger(e)
})
.emulateTransitionEnd(300) :
that.$element.focus().trigger(e)
})
}
Modal.prototype.hide = function (e) {
if (e) e.preventDefault()
e = $.Event('hide.bs.modal')
this.$element.trigger(e)
if (!this.isShown || e.isDefaultPrevented()) return
this.isShown = false
this.escape()
$(document).off('focusin.bs.modal')
this.$element
.removeClass('in')
.attr('aria-hidden', true)
.off('click.dismiss.modal')
$.support.transition && this.$element.hasClass('fade') ?
this.$element
.one($.support.transition.end, $.proxy(this.hideModal, this))
.emulateTransitionEnd(300) :
this.hideModal()
}
Modal.prototype.enforceFocus = function () {
$(document)
.off('focusin.bs.modal') // guard against infinite focus loop
.on('focusin.bs.modal', $.proxy(function (e) {
if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
this.$element.focus()
}
}, this))
}
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) {
this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide()
}, this))
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.bs.modal')
}
}
Modal.prototype.hideModal = function () {
var that = this
this.$element.hide()
this.backdrop(function () {
that.removeBackdrop()
that.$element.trigger('hidden.bs.modal')
})
}
Modal.prototype.removeBackdrop = function () {
this.$backdrop && this.$backdrop.remove()
this.$backdrop = null
}
Modal.prototype.backdrop = function (callback) {
var that = this
var animate = this.$element.hasClass('fade') ? 'fade' : ''
if (this.isShown && this.options.backdrop) {
var doAnimate = $.support.transition && animate
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.appendTo(document.body)
this.$element.on('click.dismiss.modal', $.proxy(function (e) {
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
? this.$element[0].focus.call(this.$element[0])
: this.hide.call(this)
}, this))
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
this.$backdrop.addClass('in')
if (!callback) return
doAnimate ?
this.$backdrop
.one($.support.transition.end, callback)
.emulateTransitionEnd(150) :
callback()
} else if (!this.isShown && this.$backdrop) {
this.$backdrop.removeClass('in')
$.support.transition && this.$element.hasClass('fade')?
this.$backdrop
.one($.support.transition.end, callback)
.emulateTransitionEnd(150) :
callback()
} else if (callback) {
callback()
}
}
// MODAL PLUGIN DEFINITION
// =======================
var old = $.fn.modal
$.fn.modal = function (option, _relatedTarget) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.modal')
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
if (typeof option == 'string') data[option](_relatedTarget)
else if (options.show) data.show(_relatedTarget)
})
}
$.fn.modal.Constructor = Modal
// MODAL NO CONFLICT
// =================
$.fn.modal.noConflict = function () {
$.fn.modal = old
return this
}
// MODAL DATA-API
// ==============
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
var $this = $(this)
var href = $this.attr('href')
var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
var option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
e.preventDefault()
$target
.modal(option, this)
.one('hide', function () {
$this.is(':visible') && $this.focus()
})
})
$(document)
.on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
.on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
}(window.jQuery);

View File

@@ -1,117 +0,0 @@
/* ========================================================================
* Bootstrap: popover.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#popovers
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// POPOVER PUBLIC CLASS DEFINITION
// ===============================
var Popover = function (element, options) {
this.init('popover', element, options)
}
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right'
, trigger: 'click'
, content: ''
, template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
})
// NOTE: POPOVER EXTENDS tooltip.js
// ================================
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
Popover.prototype.constructor = Popover
Popover.prototype.getDefaults = function () {
return Popover.DEFAULTS
}
Popover.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
var content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
$tip.removeClass('fade top bottom left right in')
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// this manually by checking the contents.
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
}
Popover.prototype.hasContent = function () {
return this.getTitle() || this.getContent()
}
Popover.prototype.getContent = function () {
var $e = this.$element
var o = this.options
return $e.attr('data-content')
|| (typeof o.content == 'function' ?
o.content.call($e[0]) :
o.content)
}
Popover.prototype.arrow = function () {
return this.$arrow = this.$arrow || this.tip().find('.arrow')
}
Popover.prototype.tip = function () {
if (!this.$tip) this.$tip = $(this.options.template)
return this.$tip
}
// POPOVER PLUGIN DEFINITION
// =========================
var old = $.fn.popover
$.fn.popover = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.popover.Constructor = Popover
// POPOVER NO CONFLICT
// ===================
$.fn.popover.noConflict = function () {
$.fn.popover = old
return this
}
}(window.jQuery);

View File

@@ -1,158 +0,0 @@
/* ========================================================================
* Bootstrap: scrollspy.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#scrollspy
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// SCROLLSPY CLASS DEFINITION
// ==========================
function ScrollSpy(element, options) {
var href
var process = $.proxy(this.process, this)
this.$element = $(element).is('body') ? $(window) : $(element)
this.$body = $('body')
this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
this.selector = (this.options.target
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|| '') + ' .nav li > a'
this.offsets = $([])
this.targets = $([])
this.activeTarget = null
this.refresh()
this.process()
}
ScrollSpy.DEFAULTS = {
offset: 10
}
ScrollSpy.prototype.refresh = function () {
var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
this.offsets = $([])
this.targets = $([])
var self = this
var $targets = this.$body
.find(this.selector)
.map(function () {
var $el = $(this)
var href = $el.data('target') || $el.attr('href')
var $href = /^#\w/.test(href) && $(href)
return ($href
&& $href.length
&& [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
})
.sort(function (a, b) { return a[0] - b[0] })
.each(function () {
self.offsets.push(this[0])
self.targets.push(this[1])
})
}
ScrollSpy.prototype.process = function () {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
var maxScroll = scrollHeight - this.$scrollElement.height()
var offsets = this.offsets
var targets = this.targets
var activeTarget = this.activeTarget
var i
if (scrollTop >= maxScroll) {
return activeTarget != (i = targets.last()[0]) && this.activate(i)
}
for (i = offsets.length; i--;) {
activeTarget != targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& this.activate( targets[i] )
}
}
ScrollSpy.prototype.activate = function (target) {
this.activeTarget = target
$(this.selector)
.parents('.active')
.removeClass('active')
var selector = this.selector
+ '[data-target="' + target + '"],'
+ this.selector + '[href="' + target + '"]'
var active = $(selector)
.parents('li')
.addClass('active')
if (active.parent('.dropdown-menu').length) {
active = active
.closest('li.dropdown')
.addClass('active')
}
active.trigger('activate')
}
// SCROLLSPY PLUGIN DEFINITION
// ===========================
var old = $.fn.scrollspy
$.fn.scrollspy = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.scrollspy')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
// SCROLLSPY NO CONFLICT
// =====================
$.fn.scrollspy.noConflict = function () {
$.fn.scrollspy = old
return this
}
// SCROLLSPY DATA-API
// ==================
$(window).on('load', function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);

View File

@@ -1,135 +0,0 @@
/* ========================================================================
* Bootstrap: tab.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#tabs
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// TAB CLASS DEFINITION
// ====================
var Tab = function (element) {
this.element = $(element)
}
Tab.prototype.show = function () {
var $this = this.element
var $ul = $this.closest('ul:not(.dropdown-menu)')
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
if ($this.parent('li').hasClass('active')) return
var previous = $ul.find('.active:last a')[0]
var e = $.Event('show.bs.tab', {
relatedTarget: previous
})
$this.trigger(e)
if (e.isDefaultPrevented()) return
var $target = $(selector)
this.activate($this.parent('li'), $ul)
this.activate($target, $target.parent(), function () {
$this.trigger({
type: 'shown.bs.tab'
, relatedTarget: previous
})
})
}
Tab.prototype.activate = function (element, container, callback) {
var $active = container.find('> .active')
var transition = callback
&& $.support.transition
&& $active.hasClass('fade')
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
element.addClass('active')
if (transition) {
element[0].offsetWidth // reflow for transition
element.addClass('in')
} else {
element.removeClass('fade')
}
if (element.parent('.dropdown-menu')) {
element.closest('li.dropdown').addClass('active')
}
callback && callback()
}
transition ?
$active
.one($.support.transition.end, next)
.emulateTransitionEnd(150) :
next()
$active.removeClass('in')
}
// TAB PLUGIN DEFINITION
// =====================
var old = $.fn.tab
$.fn.tab = function ( option ) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tab')
if (!data) $this.data('bs.tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tab.Constructor = Tab
// TAB NO CONFLICT
// ===============
$.fn.tab.noConflict = function () {
$.fn.tab = old
return this
}
// TAB DATA-API
// ============
$(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
e.preventDefault()
$(this).tab('show')
})
}(window.jQuery);

View File

@@ -1,386 +0,0 @@
/* ========================================================================
* Bootstrap: tooltip.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// TOOLTIP PUBLIC CLASS DEFINITION
// ===============================
var Tooltip = function (element, options) {
this.type =
this.options =
this.enabled =
this.timeout =
this.hoverState =
this.$element = null
this.init('tooltip', element, options)
}
Tooltip.DEFAULTS = {
animation: true
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover focus'
, title: ''
, delay: 0
, html: false
, container: false
}
Tooltip.prototype.init = function (type, element, options) {
this.enabled = true
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
var trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
Tooltip.prototype.getDefaults = function () {
return Tooltip.DEFAULTS
}
Tooltip.prototype.getOptions = function (options) {
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
Tooltip.prototype.getDelegateOptions = function () {
var options = {}
var defaults = this.getDefaults()
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
})
return options
}
Tooltip.prototype.enter = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
clearTimeout(self.timeout)
self.hoverState = 'in'
if (!self.options.delay || !self.options.delay.show) return self.show()
self.timeout = setTimeout(function () {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
Tooltip.prototype.leave = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
clearTimeout(self.timeout)
self.hoverState = 'out'
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.timeout = setTimeout(function () {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
Tooltip.prototype.show = function () {
var e = $.Event('show.bs.'+ this.type)
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
var $tip = this.tip()
this.setContent()
if (this.options.animation) $tip.addClass('fade')
var placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
var autoToken = /\s?auto?\s?/i
var autoPlace = autoToken.test(placement)
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
.addClass(placement)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
var pos = this.getPosition()
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (autoPlace) {
var $parent = this.$element.parent()
var orgPlacement = placement
var docScroll = document.documentElement.scrollTop || document.body.scrollTop
var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
placement
$tip
.removeClass(orgPlacement)
.addClass(placement)
}
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
this.applyPlacement(calculatedOffset, placement)
this.$element.trigger('shown.bs.' + this.type)
}
}
Tooltip.prototype.applyPlacement = function(offset, placement) {
var replace
var $tip = this.tip()
var width = $tip[0].offsetWidth
var height = $tip[0].offsetHeight
// manually read margins because getBoundingClientRect includes difference
var marginTop = parseInt($tip.css('margin-top'), 10)
var marginLeft = parseInt($tip.css('margin-left'), 10)
// we must check for NaN for ie 8/9
if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginLeft)) marginLeft = 0
offset.top = offset.top + marginTop
offset.left = offset.left + marginLeft
$tip
.offset(offset)
.addClass('in')
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (placement == 'top' && actualHeight != height) {
replace = true
offset.top = offset.top + height - actualHeight
}
if (/bottom|top/.test(placement)) {
var delta = 0
if (offset.left < 0) {
delta = offset.left * -2
offset.left = 0
$tip.offset(offset)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
}
this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
} else {
this.replaceArrow(actualHeight - height, actualHeight, 'top')
}
if (replace) $tip.offset(offset)
}
Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
}
Tooltip.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
Tooltip.prototype.hide = function () {
var that = this
var $tip = this.tip()
var e = $.Event('hide.bs.' + this.type)
function complete() {
if (that.hoverState != 'in') $tip.detach()
}
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ?
$tip
.one($.support.transition.end, complete)
.emulateTransitionEnd(150) :
complete()
this.$element.trigger('hidden.bs.' + this.type)
return this
}
Tooltip.prototype.fixTitle = function () {
var $e = this.$element
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
}
}
Tooltip.prototype.hasContent = function () {
return this.getTitle()
}
Tooltip.prototype.getPosition = function () {
var el = this.$element[0]
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
width: el.offsetWidth
, height: el.offsetHeight
}, this.$element.offset())
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
}
Tooltip.prototype.getTitle = function () {
var title
var $e = this.$element
var o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
Tooltip.prototype.tip = function () {
return this.$tip = this.$tip || $(this.options.template)
}
Tooltip.prototype.arrow = function () {
return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
}
Tooltip.prototype.validate = function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
Tooltip.prototype.enable = function () {
this.enabled = true
}
Tooltip.prototype.disable = function () {
this.enabled = false
}
Tooltip.prototype.toggleEnabled = function () {
this.enabled = !this.enabled
}
Tooltip.prototype.toggle = function (e) {
var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
}
Tooltip.prototype.destroy = function () {
this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
}
// TOOLTIP PLUGIN DEFINITION
// =========================
var old = $.fn.tooltip
$.fn.tooltip = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT
// ===================
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
return this
}
}(window.jQuery);

View File

@@ -1,56 +0,0 @@
/* ========================================================================
* Bootstrap: transition.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#transitions
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd'
, 'MozTransition' : 'transitionend'
, 'OTransition' : 'oTransitionEnd otransitionend'
, 'transition' : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
}
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
var called = false, $el = this
$(this).one($.support.transition.end, function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
return this
}
$(function () {
$.support.transition = transitionEnd()
})
}(window.jQuery);

View File

@@ -0,0 +1,604 @@
/**
* bootbox.js v4.0.0
*
* http://bootboxjs.com/license.txt
*/
// @see https://github.com/makeusabrew/bootbox/issues/71
window.bootbox = window.bootbox || (function init($, undefined) {
"use strict";
// the base DOM structure needed to create a modal
var templates = {
dialog:
"<div class='bootbox modal' tabindex='-1' role='dialog'>" +
"<div class='modal-dialog'>" +
"<div class='modal-content'>" +
"<div class='modal-body'><div class='bootbox-body'></div></div>" +
"</div>" +
"</div>" +
"</div>",
header:
"<div class='modal-header'>" +
"<h4 class='modal-title'></h4>" +
"</div>",
footer:
"<div class='modal-footer'></div>",
closeButton:
"<button type='button' class='bootbox-close-button close'>&times;</button>",
form:
"<form class='bootbox-form'></form>",
inputs: {
text:
"<input class='bootbox-input form-control' autocomplete=off type=text />"
}
};
// cache a reference to the jQueryfied body element
var appendTo = $("body");
var defaults = {
// default language
locale: "en",
// show backdrop or not
backdrop: true,
// animate the modal in/out
animate: true,
// additional class string applied to the top level dialog
className: null,
// whether or not to include a close button
closeButton: true,
// show the dialog immediately by default
show: true
};
// our public object; augmented after our private API
var exports = {};
/**
* @private
*/
function _t(key) {
var locale = locales[defaults.locale];
return locale ? locale[key] : locales.en[key];
}
function processCallback(e, dialog, callback) {
e.preventDefault();
// by default we assume a callback will get rid of the dialog,
// although it is given the opportunity to override this
// so, if the callback can be invoked and it *explicitly returns false*
// then we'll set a flag to keep the dialog active...
var preserveDialog = $.isFunction(callback) && callback(e) === false;
// ... otherwise we'll bin it
if (!preserveDialog) {
dialog.modal("hide");
}
}
function getKeyLength(obj) {
// @TODO defer to Object.keys(x).length if available?
var k, t = 0;
for (k in obj) {
t ++;
}
return t;
}
function each(collection, iterator) {
var index = 0;
$.each(collection, function(key, value) {
iterator(key, value, index++);
});
}
function sanitize(options) {
var buttons;
var total;
if (typeof options !== "object") {
throw new Error("Please supply an object of options");
}
if (!options.message) {
throw new Error("Please specify a message");
}
// make sure any supplied options take precedence over defaults
options = $.extend({}, defaults, options);
if (!options.buttons) {
options.buttons = {};
}
// we only support Bootstrap's "static" and false backdrop args
// supporting true would mean you could dismiss the dialog without
// explicitly interacting with it
options.backdrop = options.backdrop ? "static" : false;
buttons = options.buttons;
total = getKeyLength(buttons);
each(buttons, function(key, button, index) {
if ($.isFunction(button)) {
// short form, assume value is our callback. Since button
// isn't an object it isn't a reference either so re-assign it
button = buttons[key] = {
callback: button
};
}
// before any further checks make sure by now button is the correct type
if ($.type(button) !== "object") {
throw new Error("button with key " + key + " must be an object");
}
if (!button.label) {
// the lack of an explicit label means we'll assume the key is good enough
button.label = key;
}
if (!button.className) {
if (total <= 2 && index === total-1) {
// always add a primary to the main option in a two-button dialog
button.className = "btn-primary";
} else {
button.className = "btn-default";
}
}
});
return options;
}
function mapArguments(args, properties) {
var argn = args.length;
var options = {};
if (argn < 1 || argn > 2) {
throw new Error("Invalid argument length");
}
if (argn === 2 || typeof args[0] === "string") {
options[properties[0]] = args[0];
options[properties[1]] = args[1];
} else {
options = args[0];
}
return options;
}
function mergeArguments(defaults, args, properties) {
return $.extend(true, {}, defaults, mapArguments(args, properties));
}
function mergeButtons(labels, args, properties) {
return validateButtons(
mergeArguments(createButtons.apply(null, labels), args, properties),
labels
);
}
function createLabels() {
var buttons = {};
for (var i = 0, j = arguments.length; i < j; i++) {
var argument = arguments[i];
var key = argument.toLowerCase();
var value = argument.toUpperCase();
buttons[key] = {
label: _t(value)
};
}
return buttons;
}
function createButtons() {
return {
buttons: createLabels.apply(null, arguments)
};
}
function validateButtons(options, buttons) {
var allowedButtons = {};
each(buttons, function(key, value) {
allowedButtons[value] = true;
});
each(options.buttons, function(key) {
if (allowedButtons[key] === undefined) {
throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
}
});
return options;
}
exports.alert = function() {
var options;
options = mergeButtons(["ok"], arguments, ["message", "callback"]);
if (options.callback && !$.isFunction(options.callback)) {
throw new Error("alert requires callback property to be a function when provided");
}
/**
* overrides
*/
options.buttons.ok.callback = options.onEscape = function() {
if ($.isFunction(options.callback)) {
return options.callback();
}
return true;
};
return exports.dialog(options);
};
exports.confirm = function() {
var options;
options = mergeButtons(["cancel", "confirm"], arguments, ["message", "callback"]);
/**
* overrides; undo anything the user tried to set they shouldn't have
*/
options.buttons.cancel.callback = options.onEscape = function() {
return options.callback(false);
};
options.buttons.confirm.callback = function() {
return options.callback(true);
};
// confirm specific validation
if (!$.isFunction(options.callback)) {
throw new Error("confirm requires a callback");
}
return exports.dialog(options);
};
exports.prompt = function() {
var options;
var defaults;
var dialog;
var form;
var input;
var shouldShow;
// we have to create our form first otherwise
// its value is undefined when gearing up our options
// @TODO this could be solved by allowing message to
// be a function instead...
form = $(templates.form);
defaults = {
buttons: createLabels("cancel", "confirm"),
value: ""
};
options = validateButtons(
mergeArguments(defaults, arguments, ["title", "callback"]),
["cancel", "confirm"]
);
// capture the user's show value; we always set this to false before
// spawning the dialog to give us a chance to attach some handlers to
// it, but we need to make sure we respect a preference not to show it
shouldShow = (options.show === undefined) ? true : options.show;
/**
* overrides; undo anything the user tried to set they shouldn't have
*/
options.message = form;
options.buttons.cancel.callback = options.onEscape = function() {
return options.callback(null);
};
options.buttons.confirm.callback = function() {
return options.callback(input.val());
};
options.show = false;
// prompt specific validation
if (!options.title) {
throw new Error("prompt requires a title");
}
if (!$.isFunction(options.callback)) {
throw new Error("prompt requires a callback");
}
// create the input
input = $(templates.inputs.text);
input.val(options.value);
// now place it in our form
form.append(input);
form.on("submit", function(e) {
e.preventDefault();
// @TODO can we actually click *the* button object instead?
// e.g. buttons.confirm.click() or similar
dialog.find(".btn-primary").click();
});
dialog = exports.dialog(options);
// clear the existing handler focusing the submit button...
dialog.off("shown.bs.modal");
// ...and replace it with one focusing our input, if possible
dialog.on("shown.bs.modal", function() {
input.focus();
});
if (shouldShow === true) {
dialog.modal("show");
}
return dialog;
};
exports.dialog = function(options) {
options = sanitize(options);
var dialog = $(templates.dialog);
var body = dialog.find(".modal-body");
var buttons = options.buttons;
var buttonStr = "";
var callbacks = {
onEscape: options.onEscape
};
each(buttons, function(key, button) {
// @TODO I don't like this string appending to itself; bit dirty. Needs reworking
// can we just build up button elements instead? slower but neater. Then button
// can just become a template too
buttonStr += "<button data-bb-handler='" + key + "' type='button' class='btn " + button.className + "'>" + button.label + "</button>";
callbacks[key] = button.callback;
});
body.find(".bootbox-body").html(options.message);
if (options.animate === true) {
dialog.addClass("fade");
}
if (options.className) {
dialog.addClass(options.className);
}
if (options.title) {
body.before(templates.header);
}
if (options.closeButton) {
var closeButton = $(templates.closeButton);
if (options.title) {
dialog.find(".modal-header").prepend(closeButton);
} else {
closeButton.css("margin-top", "-10px").prependTo(body);
}
}
if (options.title) {
dialog.find(".modal-title").html(options.title);
}
if (buttonStr.length) {
body.after(templates.footer);
dialog.find(".modal-footer").html(buttonStr);
}
/**
* Bootstrap event listeners; used handle extra
* setup & teardown required after the underlying
* modal has performed certain actions
*/
dialog.on("hidden.bs.modal", function(e) {
// ensure we don't accidentally intercept hidden events triggered
// by children of the current dialog. We shouldn't anymore now BS
// namespaces its events; but still worth doing
if (e.target === this) {
dialog.remove();
}
});
/*
dialog.on("show.bs.modal", function() {
// sadly this doesn't work; show is called *just* before
// the backdrop is added so we'd need a setTimeout hack or
// otherwise... leaving in as would be nice
if (options.backdrop) {
dialog.next(".modal-backdrop").addClass("bootbox-backdrop");
}
});
*/
dialog.on("shown.bs.modal", function() {
dialog.find(".btn-primary:first").focus();
});
/**
* Bootbox event listeners; experimental and may not last
* just an attempt to decouple some behaviours from their
* respective triggers
*/
dialog.on("escape.close.bb", function(e) {
if (callbacks.onEscape) {
processCallback(e, dialog, callbacks.onEscape);
}
});
/**
* Standard jQuery event listeners; used to handle user
* interaction with our dialog
*/
dialog.on("click", ".modal-footer button", function(e) {
var callbackKey = $(this).data("bb-handler");
processCallback(e, dialog, callbacks[callbackKey]);
});
dialog.on("click", ".bootbox-close-button", function(e) {
// onEscape might be falsy but that's fine; the fact is
// if the user has managed to click the close button we
// have to close the dialog, callback or not
processCallback(e, dialog, callbacks.onEscape);
});
dialog.on("keyup", function(e) {
if (e.which === 27) {
dialog.trigger("escape.close.bb");
}
});
// the remainder of this method simply deals with adding our
// dialogent to the DOM, augmenting it with Bootstrap's modal
// functionality and then giving the resulting object back
// to our caller
appendTo.append(dialog);
dialog.modal({
backdrop: options.backdrop,
keyboard: false,
show: false
});
if (options.show) {
dialog.modal("show");
}
// @TODO should we return the raw element here or should
// we wrap it in an object on which we can expose some neater
// methods, e.g. var d = bootbox.alert(); d.hide(); instead
// of d.modal("hide");
/*
function BBDialog(elem) {
this.elem = elem;
}
BBDialog.prototype = {
hide: function() {
return this.elem.modal("hide");
},
show: function() {
return this.elem.modal("show");
}
};
*/
return dialog;
};
exports.setDefaults = function(values) {
$.extend(defaults, values);
};
exports.hideAll = function() {
$(".bootbox").modal("hide");
};
/**
* standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
* unlikely to be required. If this gets too large it can be split out into separate JS files.
*/
var locales = {
br : {
OK : "OK",
CANCEL : "Cancelar",
CONFIRM : "Sim"
},
da : {
OK : "OK",
CANCEL : "Annuller",
CONFIRM : "Accepter"
},
de : {
OK : "OK",
CANCEL : "Abbrechen",
CONFIRM : "Akzeptieren"
},
en : {
OK : "OK",
CANCEL : "Cancel",
CONFIRM : "OK"
},
es : {
OK : "OK",
CANCEL : "Cancelar",
CONFIRM : "Aceptar"
},
fi : {
OK : "OK",
CANCEL : "Peruuta",
CONFIRM : "OK"
},
fr : {
OK : "OK",
CANCEL : "Annuler",
CONFIRM : "D'accord"
},
it : {
OK : "OK",
CANCEL : "Annulla",
CONFIRM : "Conferma"
},
nl : {
OK : "OK",
CANCEL : "Annuleren",
CONFIRM : "Accepteren"
},
pl : {
OK : "OK",
CANCEL : "Anuluj",
CONFIRM : "Potwierdź"
},
ru : {
OK : "OK",
CANCEL : "Отмена",
CONFIRM : "Применить"
},
zh_CN : {
OK : "OK",
CANCEL : "取消",
CONFIRM : "确认"
},
zh_TW : {
OK : "OK",
CANCEL : "取消",
CONFIRM : "確認"
}
};
exports.init = function(_$) {
window.bootbox = init(_$ || $);
};
return exports;
}(window.jQuery));

File diff suppressed because one or more lines are too long

View File

@@ -1,120 +0,0 @@
!function ($) {
"use strict"; // jshint ;_;
/* MAGNIFY PUBLIC CLASS DEFINITION
* =============================== */
var Magnify = function (element, options) {
this.init('magnify', element, options)
}
Magnify.prototype = {
constructor: Magnify
, init: function (type, element, options) {
var event = 'mousemove'
, eventOut = 'mouseleave';
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.nativeWidth = 0
this.nativeHeight = 0
this.$element.wrap('<div class="magnify" \>');
this.$element.parent('.magnify').append('<div class="magnify-large" \>');
this.$element.siblings(".magnify-large").css("background","url('" + this.$element.attr("src") + "') no-repeat");
this.$element.parent('.magnify').on(event + '.' + this.type, $.proxy(this.check, this));
this.$element.parent('.magnify').on(eventOut + '.' + this.type, $.proxy(this.check, this));
}
, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
, check: function (e) {
var container = $(e.currentTarget);
var self = container.children('img');
var mag = container.children(".magnify-large");
// Get the native dimensions of the image
if(!this.nativeWidth && !this.nativeHeight) {
var image = new Image();
image.src = self.attr("src");
this.nativeWidth = image.width;
this.nativeHeight = image.height;
} else {
var magnifyOffset = container.offset();
var mx = e.pageX - magnifyOffset.left;
var my = e.pageY - magnifyOffset.top;
if (mx < container.width() && my < container.height() && mx > 0 && my > 0) {
mag.fadeIn(100);
} else {
mag.fadeOut(100);
}
if(mag.is(":visible"))
{
var rx = Math.round(mx/container.width()*this.nativeWidth - mag.width()/2)*-1;
var ry = Math.round(my/container.height()*this.nativeHeight - mag.height()/2)*-1;
var bgp = rx + "px " + ry + "px";
var px = mx - mag.width()/2;
var py = my - mag.height()/2;
mag.css({left: px, top: py, backgroundPosition: bgp});
}
}
}
}
/* MAGNIFY PLUGIN DEFINITION
* ========================= */
$.fn.magnify = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('magnify')
, options = typeof option == 'object' && option
if (!data) $this.data('tooltip', (data = new Magnify(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.magnify.Constructor = Magnify
$.fn.magnify.defaults = {
delay: 0
}
/* MAGNIFY DATA-API
* ================ */
$(window).on('load', function () {
$('[data-toggle="magnify"]').each(function () {
var $mag = $(this);
$mag.magnify()
})
})
} ( window.jQuery );

View File

@@ -1 +0,0 @@
!function(e){"use strict";var t=function(e,t){this.init("magnify",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i="mousemove",s="mouseleave";this.type=t;this.$element=e(n);this.options=this.getOptions(r);this.nativeWidth=0;this.nativeHeight=0;this.$element.wrap('<div class="magnify" >');this.$element.parent(".magnify").append('<div class="magnify-large" >');this.$element.siblings(".magnify-large").css("background","url('"+this.$element.attr("src")+"') no-repeat");this.$element.parent(".magnify").on(i+"."+this.type,e.proxy(this.check,this));this.$element.parent(".magnify").on(s+"."+this.type,e.proxy(this.check,this))},getOptions:function(t){t=e.extend({},e.fn[this.type].defaults,t,this.$element.data());t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay});return t},check:function(t){var n=e(t.currentTarget),r=n.children("img"),i=n.children(".magnify-large");if(!this.nativeWidth&&!this.nativeHeight){var s=new Image;s.src=r.attr("src");this.nativeWidth=s.width;this.nativeHeight=s.height}else{var o=n.offset(),u=t.pageX-o.left,a=t.pageY-o.top;u<n.width()&&a<n.height()&&u>0&&a>0?i.fadeIn(100):i.fadeOut(100);if(i.is(":visible")){var f=Math.round(u/n.width()*this.nativeWidth-i.width()/2)*-1,l=Math.round(a/n.height()*this.nativeHeight-i.height()/2)*-1,c=f+"px "+l+"px",h=u-i.width()/2,p=a-i.height()/2;i.css({left:h,top:p,backgroundPosition:c})}}}};e.fn.magnify=function(n){return this.each(function(){var r=e(this),i=r.data("magnify"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s));typeof n=="string"&&i[n]()})};e.fn.magnify.Constructor=t;e.fn.magnify.defaults={delay:0};e(window).on("load",function(){e('[data-toggle="magnify"]').each(function(){var t=e(this);t.magnify()})})}(window.jQuery);

View File

@@ -1,323 +0,0 @@
/**
* menu-aim is a jQuery plugin for dropdown menus that can differentiate
* between a user trying hover over a dropdown item vs trying to navigate into
* a submenu's contents.
*
* menu-aim assumes that you have are using a menu with submenus that expand
* to the menu's right. It will fire events when the user's mouse enters a new
* dropdown item *and* when that item is being intentionally hovered over.
*
* __________________________
* | Monkeys >| Gorilla |
* | Gorillas >| Content |
* | Chimps >| Here |
* |___________|____________|
*
* In the above example, "Gorillas" is selected and its submenu content is
* being shown on the right. Imagine that the user's cursor is hovering over
* "Gorillas." When they move their mouse into the "Gorilla Content" area, they
* may briefly hover over "Chimps." This shouldn't close the "Gorilla Content"
* area.
*
* This problem is normally solved using timeouts and delays. menu-aim tries to
* solve this by detecting the direction of the user's mouse movement. This can
* make for quicker transitions when navigating up and down the menu. The
* experience is hopefully similar to amazon.com/'s "Shop by Department"
* dropdown.
*
* Use like so:
*
* $("#menu").menuAim({
* activate: $.noop, // fired on row activation
* deactivate: $.noop // fired on row deactivation
* });
*
* ...to receive events when a menu's row has been purposefully (de)activated.
*
* The following options can be passed to menuAim. All functions execute with
* the relevant row's HTML element as the execution context ('this'):
*
* .menuAim({
* // Function to call when a row is purposefully activated. Use this
* // to show a submenu's content for the activated row.
* activate: function() {},
*
* // Function to call when a row is deactivated.
* deactivate: function() {},
*
* // Function to call when mouse enters a menu row. Entering a row
* // does not mean the row has been activated, as the user may be
* // mousing over to a submenu.
* enter: function() {},
*
* // Function to call when mouse exits a menu row.
* exit: function() {},
*
* // Selector for identifying which elements in the menu are rows
* // that can trigger the above events. Defaults to "> li".
* rowSelector: "> li",
*
* // You may have some menu rows that aren't submenus and therefore
* // shouldn't ever need to "activate." If so, filter submenu rows w/
* // this selector. Defaults to "*" (all elements).
* submenuSelector: "*",
*
* // Direction the submenu opens relative to the main menu. Can be
* // left, right, above, or below. Defaults to "right".
* submenuDirection: "right"
* });
*
* https://github.com/kamens/jQuery-menu-aim
*/
(function($) {
$.fn.menuAim = function(opts) {
// Initialize menu-aim for all elements in jQuery collection
this.each(function() {
init.call(this, opts);
});
return this;
};
function init(opts) {
var $menu = $(this),
activeRow = null,
mouseLocs = [],
lastDelayLoc = null,
timeoutId = null,
options = $.extend({
rowSelector: "> li",
submenuSelector: "*",
submenuDirection: "right",
tolerance: 75, // bigger = more forgivey when entering submenu
enter: $.noop,
exit: $.noop,
activate: $.noop,
deactivate: $.noop,
exitMenu: $.noop
}, opts);
var MOUSE_LOCS_TRACKED = 3, // number of past mouse locations to track
DELAY = 300; // ms delay when user appears to be entering submenu
/**
* Keep track of the last few locations of the mouse.
*/
var mousemoveDocument = function(e) {
mouseLocs.push({x: e.pageX, y: e.pageY});
if (mouseLocs.length > MOUSE_LOCS_TRACKED) {
mouseLocs.shift();
}
};
/**
* Cancel possible row activations when leaving the menu entirely
*/
var mouseleaveMenu = function() {
if (timeoutId) {
clearTimeout(timeoutId);
}
// If exitMenu is supplied and returns true, deactivate the
// currently active row on menu exit.
if (options.exitMenu(this)) {
if (activeRow) {
options.deactivate(activeRow);
}
activeRow = null;
}
};
/**
* Trigger a possible row activation whenever entering a new row.
*/
var mouseenterRow = function() {
if (timeoutId) {
// Cancel any previous activation delays
clearTimeout(timeoutId);
}
options.enter(this);
possiblyActivate(this);
},
mouseleaveRow = function() {
options.exit(this);
};
/*
* Immediately activate a row if the user clicks on it.
*/
var clickRow = function() {
activate(this);
};
/**
* Activate a menu row.
*/
var activate = function(row) {
if (row == activeRow) {
return;
}
if (activeRow) {
options.deactivate(activeRow);
}
options.activate(row);
activeRow = row;
};
/**
* Possibly activate a menu row. If mouse movement indicates that we
* shouldn't activate yet because user may be trying to enter
* a submenu's content, then delay and check again later.
*/
var possiblyActivate = function(row) {
var delay = activationDelay();
if (delay) {
timeoutId = setTimeout(function() {
possiblyActivate(row);
}, delay);
} else {
activate(row);
}
};
/**
* Return the amount of time that should be used as a delay before the
* currently hovered row is activated.
*
* Returns 0 if the activation should happen immediately. Otherwise,
* returns the number of milliseconds that should be delayed before
* checking again to see if the row should be activated.
*/
var activationDelay = function() {
if (!activeRow || !$(activeRow).is(options.submenuSelector)) {
// If there is no other submenu row already active, then
// go ahead and activate immediately.
return 0;
}
var offset = $menu.offset(),
upperLeft = {
x: offset.left,
y: offset.top - options.tolerance
},
upperRight = {
x: offset.left + $menu.outerWidth(),
y: upperLeft.y
},
lowerLeft = {
x: offset.left,
y: offset.top + $menu.outerHeight() + options.tolerance
},
lowerRight = {
x: offset.left + $menu.outerWidth(),
y: lowerLeft.y
},
loc = mouseLocs[mouseLocs.length - 1],
prevLoc = mouseLocs[0];
if (!loc) {
return 0;
}
if (!prevLoc) {
prevLoc = loc;
}
if (prevLoc.x < offset.left || prevLoc.x > lowerRight.x ||
prevLoc.y < offset.top || prevLoc.y > lowerRight.y) {
// If the previous mouse location was outside of the entire
// menu's bounds, immediately activate.
return 0;
}
if (lastDelayLoc &&
loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y) {
// If the mouse hasn't moved since the last time we checked
// for activation status, immediately activate.
return 0;
}
// Detect if the user is moving towards the currently activated
// submenu.
//
// If the mouse is heading relatively clearly towards
// the submenu's content, we should wait and give the user more
// time before activating a new row. If the mouse is heading
// elsewhere, we can immediately activate a new row.
//
// We detect this by calculating the slope formed between the
// current mouse location and the upper/lower right points of
// the menu. We do the same for the previous mouse location.
// If the current mouse location's slopes are
// increasing/decreasing appropriately compared to the
// previous's, we know the user is moving toward the submenu.
//
// Note that since the y-axis increases as the cursor moves
// down the screen, we are looking for the slope between the
// cursor and the upper right corner to decrease over time, not
// increase (somewhat counterintuitively).
function slope(a, b) {
return (b.y - a.y) / (b.x - a.x);
};
var decreasingCorner = upperRight,
increasingCorner = lowerRight;
// Our expectations for decreasing or increasing slope values
// depends on which direction the submenu opens relative to the
// main menu. By default, if the menu opens on the right, we
// expect the slope between the cursor and the upper right
// corner to decrease over time, as explained above. If the
// submenu opens in a different direction, we change our slope
// expectations.
if (options.submenuDirection == "left") {
decreasingCorner = lowerLeft;
increasingCorner = upperLeft;
} else if (options.submenuDirection == "below") {
decreasingCorner = lowerRight;
increasingCorner = lowerLeft;
} else if (options.submenuDirection == "above") {
decreasingCorner = upperLeft;
increasingCorner = upperRight;
}
var decreasingSlope = slope(loc, decreasingCorner),
increasingSlope = slope(loc, increasingCorner),
prevDecreasingSlope = slope(prevLoc, decreasingCorner),
prevIncreasingSlope = slope(prevLoc, increasingCorner);
if (decreasingSlope < prevDecreasingSlope &&
increasingSlope > prevIncreasingSlope) {
// Mouse is moving from previous location towards the
// currently activated submenu. Delay before activating a
// new menu row, because user may be moving into submenu.
lastDelayLoc = loc;
return DELAY;
}
lastDelayLoc = null;
return 0;
};
/**
* Hook up initial menu events
*/
$menu
.mouseleave(mouseleaveMenu)
.find(options.rowSelector)
.mouseenter(mouseenterRow)
.mouseleave(mouseleaveRow)
.click(clickRow);
$(document).mousemove(mousemoveDocument);
};
})(jQuery);

View File

@@ -1,11 +1,18 @@
/* JQUERY PREVENT CONFLICT */
(function($) {
/* ------------------------------------------------------------------
onLoad Function -------------------------------------------------- */
$(document).ready(function(){
// Loader
var $loader = $('<div class="loader"></div>');
$('body').append($loader);
// Display loader if we do ajax call
$(document)
.ajaxStart(function() { $loader.show(); })
.ajaxStop(function(){ $loader.hide(); });
// Main Navigation Hover
$('.nav-main')
@@ -30,6 +37,29 @@
selector: '[data-toggle=tooltip]'
});
// Confirm Dialog
$(document).on('click.confirm', '[data-toggle="confirm"]', function (e) {
var $this = $(this),
href = $this.attr('href'),
title = $this.attr('data-confirm-title') ? $this.attr('data-confirm-title') : 'Are you sure?';
bootbox.confirm(title, function(confirm) {
if(confirm){
if(href){
window.location.href = href;
} else {
// If forms
var $form = $this.closest("form");
if($form.size() > 0){
$form.submit();
}
}
}
});
return false;
});
// Toolbar
var $category_products = $('#category-products');
if($category_products.size() > 0){
@@ -40,7 +70,9 @@
if( ($(this).hasClass('btn-grid') && $parent.hasClass('grid')) || ($(this).hasClass('btn-list') && $parent.hasClass('list')))
return;
$parent.toggleClass('grid').toggleClass('list');
// Add loader effect
$loader.show();
setTimeout(function(){ $parent.toggleClass('grid').toggleClass('list'); $loader.hide(); }, 400);
return false;
});
@@ -89,6 +121,7 @@
$form
.on('change.filter', ':checkbox', function(){
$loader.show();
$form.submit();
})
.find('.group-btn > .btn').addClass('sr-only');
@@ -126,6 +159,78 @@
}).filter(':has(:checked)').addClass('active');
});
if($("body").is(".page-product")){
var $quantityInput = $("#quantity");
var $btnAddToCart = $(".btn_add_to_cart", $("#form-product-details"));
var $productMeta = $("#stockInformations");
var $inStock = $(".in",$productMeta);
var $outOfStock = $(".out",$productMeta);
var $old_price_container = $(".old-price", $("#product-details"));
// Switch Quantity in product page
$("select", $(".product-options")).change(function(){
var $select_quantity = $(this).find(":selected").attr("data-quantity");
var $old_price = $(this).find(":selected").attr("data-old-price");
var $best_price = $(this).find(":selected").attr("data-price");
$quantityInput.attr("max", $select_quantity);
// Show Out Of Stock OR In Stock
if($select_quantity == 0){
$btnAddToCart.attr("disabled", true);
$productMeta.removeClass("in-stock");
$productMeta.addClass("out-of-stock");
$productMeta.attr("href", "http://schema.org/OutOfStock");
$outOfStock.show();
$inStock.hide();
}else{
$btnAddToCart.attr("disabled", false);
$productMeta.removeClass("out-of-stock");
$productMeta.addClass("in-stock");
$productMeta.attr("href", "http://schema.org/InStock");
$inStock.show();
$outOfStock.hide();
}
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){
$quantityInput.val($select_quantity);
}
if($old_price_container.size() > 0 ){
$(".price", $old_price_container).html($old_price);
$(".price", $(".special-price")).html($best_price);
}else{
$(".price", $(".regular-price")).html($best_price);
}
}).change();
$quantityInput.focusout(function() {
$quantityInput.attr("max", $select_quantity);
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){
$quantityInput.val($select_quantity);
}
});
}
$('#limit-top').change(function(e){
window.location = $(this).val()
});

View File

@@ -1,6 +1,7 @@
/* FONT PATH
* -------------------------- */
/*
@font-face {
font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=@{FontAwesomeVersion}');
@@ -11,4 +12,15 @@
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
}*/
@font-face {
font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=3');
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=3') format('embedded-opentype'),
url('@{FontAwesomePath}/fontawesome-webfont.woff?v=3') format('woff'),
url('@{FontAwesomePath}/fontawesome-webfont.ttf?v=3') format('truetype'),
url('@{FontAwesomePath}/fontawesome-webfont.svg?v=3#fontawesomeregular') format('svg');
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
}

View File

@@ -1,20 +0,0 @@
//
// Magnifier
// ---------------------------------------------------------------------------------------------------------------------
// Parent container
.magnify {
position: relative;
cursor:none;
}
// Magnifying glass
.magnify-large {
position: absolute;
display: none;
width: 175px; height: 175px;
@shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
.box-shadow(@shadow);
.border-radius(100%);
z-index:10;
}

View File

@@ -2,9 +2,6 @@
/* Bootstrap */
@import "bootstrap/bootstrap.less";
// Magnifying glass
@import "plugins/bootstrap-magnify/bootstrap-magnify.less";
/* FontAwesome */
@import "fontawesome/font-awesome.less";

View File

@@ -22,7 +22,6 @@
&.btn-checkout,
&.btn-checkout-next,
&.btn-checkout-home,
&.btn-filter,
&.btn-forgot,
&.btn-login,
&.btn-proceed-checkout,
@@ -44,8 +43,10 @@
// Keep old style button
&.btn-add-address,
&.btn-coupon,
&.btn-filter,
&.btn-grid,
&.btn-list,
&.btn-login-mini,
&.btn-search,
&.btn-subscribe { .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); }

View File

@@ -1,5 +1,13 @@
// Thelia : Shopping Cart
// Cart Empty
.cart-empty { margin: 0; padding: 40px; }
// Cart Mini
.table-cart-mini { margin-bottom: 0; }
// Cart
.table-cart {
.table-bordered;
@@ -70,3 +78,18 @@
}
}
// Message if no product in the cart
.cart-warning {
clear: both;
.alert; .alert-warning;
margin-bottom: 0;
text-align: center;
> a { color: inherit; }
&:before {
.icon(@warning-sign);
display: block;
font-size: 2.2em;
}
}

View File

@@ -9,10 +9,18 @@
}
// Form Login Mini
#form-login-mini {
.form-control { .input-sm; }
.btn { .btn-sm; }
width: 200px;
}
// Form Login
#form-login,
#form-forgotpassword {
background: #f5f5f5;;
background: #f5f5f5;
padding: 45px;
legend {
@@ -48,7 +56,8 @@
.control-input { .make-sm-column(5); }
}
.group-primary,
.group-agreed {
.group-agreed,
.group-newsletter {
.control-input { .make-sm-column-offset(3); .make-sm-column(5); }
}
.group-btn {

View File

@@ -6,6 +6,18 @@
// Collapse
.no-js .collapse { display: block!important; }
// Loader (Overlay)
.loader {
position: fixed;
background: #fff url(../img/ajax-loader.gif) no-repeat center center;
background-color: rgba(255,255,255,.5);
display: none;
left: 0; top: 0;
width: 100%;height: 100%;
z-index: 100;
}
.oldie { position: absolute; }
// thumbnail
.thumbnail {
&.active,

View File

@@ -1,6 +1,5 @@
// Thelia
@import "variables.less";
@import "path.less";
// Thelia : Layout
@import "global.less";

View File

@@ -3,35 +3,26 @@
.navbar {
.navbar-default;
.navbar-brand { .visible-xs; } // Visible only Small screen
/*.nav-main {
font-size: @navbar-font-size;
li > a {
color: @navbar-default-link-color;
padding: @navbar-link-padding;
&:hover,
&:focus {
color: @navbar-default-link-hover-color;
background-color: @navbar-default-link-hover-bg;
}
// Uncollapse the nav
.navbar-cart {
@media (min-width: @grid-float-breakpoint) {
padding-top: ((@navbar-height - @line-height-computed) / 2);
padding-bottom: ((@navbar-height - @line-height-computed) / 2);
.dropdown > a {
.dropdown-toggle;
&:after {
float: none;
}
}
.active > a {
color: @navbar-default-link-active-color;
background-color: @navbar-default-link-active-bg;
}
.open > a {
color: @navbar-default-link-hover-color!important;
background-color: @navbar-default-link-hover-bg!important;
.dropdown-menu {
@media (max-width: @grid-float-breakpoint) { display: none; }
margin: 0; padding: 20px;
&.cart-content {
width: 350px;
> p { margin: 0; }
}
}
.cart-not-empty .cart-content { border-top: none; padding: 0; }
}
}*/
// Subnav Links
@media (min-width: @grid-float-breakpoint) {
@@ -40,13 +31,6 @@ li > a {
border: 1px solid @navbar-subnav-border;
border-radius: @navbar-subnav-border-radius;
.box-shadow(@navbar-subnav-shadow);
/*
float: left;
min-width: 160px;
position: absolute;
top: 100%; left: 0;
z-index: @zindex-dropdown;
*/
// Links within the sub navigation
> li > a {
@@ -89,106 +73,6 @@ li > a {
}
}
}
/*
.subnav {
position: relative;
> ul {
//display: none; // none by default, but block on "open" of the menu
font-size: @font-size-base;
list-style: none;
margin: 0; padding: 0;
// Links within the sub navigation
> li > a {
clear: both;
display: block;
font-weight: normal;
line-height: @line-height-base;
white-space: nowrap; // prevent links from randomly breaking onto new lines
&:hover,
&:focus {
text-decoration: none;
}
}
// Active state
> .active > a {
&,
&:hover,
&:focus {
outline: 0;
text-decoration: none;
}
}
@media (min-width: @grid-float-breakpoint) {
background-color: @navbar-subnav-bg;
background-clip: padding-box;
border: 1px solid @navbar-subnav-border;
border-radius: @navbar-subnav-border-radius;
.box-shadow(@navbar-subnav-shadow);
float: left;
min-width: 160px;
position: absolute;
top: 100%; left: 0;
z-index: @zindex-dropdown;
// Links within the sub navigation
> li > a {
color: @navbar-subnav-link-color;
padding: @navbar-subnav-link-padding;
// Hover/Focus state
&:hover,
&:focus {
color: @navbar-subnav-link-hover-color;
background-color: @navbar-subnav-link-hover-bg;
}
}
// Active state
> .active > a {
&,
&:hover,
&:focus {
background-color: @navbar-subnav-link-hover-bg;
color: @navbar-subnav-link-hover-color;
}
}
}
}
/* Add support for multilevel dropdown menus
.subnav {
> ul {
top:0; left: 100%;
}
.accordion-toggle:after {
float:right;
padding-left: .3em;
.icon(@chevron-down);
@media (min-width: @screen-desktop) { .icon(@chevron-right); margin-right: -14px; padding-left: 0; }
}
}*/
// Sub
/*
> .active > a,
> .open > a {
&,
&:hover,
&:focus {
background-color: @navbar-subnav-link-hover-bg;
color: @navbar-subnav-link-hover-color;
}
}
*//*
}
.navbar-nav > .subnav > ul { border-top-color: @navbar-default-link-hover-bg; }
*/
}

View File

@@ -1,14 +0,0 @@
/* FONT PATH
* -------------------------- */
@font-face {
font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot');
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix') format('embedded-opentype'),
url('@{FontAwesomePath}/fontawesome-webfont.woff') format('woff'),
url('@{FontAwesomePath}/fontawesome-webfont.ttf') format('truetype'),
url('@{FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular') format('svg');
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
}

View File

@@ -6,9 +6,10 @@
.price {
color: @brand-primary;
font-size: ceil(@font-size-base * 1.5);
font-size: ceil(@font-size-base * 1.4);
font-weight: bold;
font-style: italic;
white-space: nowrap;
}
// Regular price

View File

@@ -15,10 +15,20 @@
.in-stock {
font-style: italic;
text-transform: uppercase;
.quantity{
font-style: italic;
}
}
// Out of Stock
.out-of-stock {
font-style: italic; font-weight: bold;
text-transform: uppercase;
}
// Out of Stock
.out-of-stock {}
#stockInformations{
}
}

View File

@@ -1,9 +1,11 @@
// Body padding required with the fixed navbar (By default, the navbar is 50px high.)
/*
body { padding-top: 80px; }
.navbar {
.navbar-fixed-top;
}
*/
.page-header {
border: none;
@@ -63,6 +65,16 @@ label { font-weight: 600; }
margin-right: .5em;
}
}
> a.cart {
&:hover,
&:focus {
> .badge {
background-color: #fff;
color: @brand-primary;
}
}
}
&.cart-not-empty {
> a.cart {
background-color: @brand-primary;
color: #fff;
@@ -86,6 +98,7 @@ label { font-weight: 600; }
}
}
}
}
.navbar-nav {
@media (min-width: @grid-float-breakpoint) {
.list-subnav {
@@ -151,7 +164,7 @@ header {
/* Custom button */
.btn-primary {
.page .btn-primary {
border-left: 3px solid lighten(@brand-primary, 20%);
.border-radius(0);
color: #fff;
@@ -247,6 +260,7 @@ header {
content: @shopping-cart;
font-size: 1.3em;
}
}
// Cart - Remove button
@@ -309,7 +323,7 @@ td.product,
.special-price {
.price {
display: block;
font-size: 25px; line-height: 25px;
font-size: 20px; line-height: 25px;
font-style: italic;
}
}
@@ -410,6 +424,7 @@ td.product,
@media (min-width: @screen-desktop) {
.product-image { padding-bottom: 40px; }
.product-info {
.transition(height 300ms linear);
position: absolute;
bottom: 0;
width: 100%; height: 50px;
@@ -419,7 +434,6 @@ td.product,
&:focus {
cursor: pointer;
height: 140px;
.transition(height 300ms linear);
}
}
}
@@ -499,6 +513,7 @@ td.product,
}
.product-btn {
min-height: 26px;
.btn-cart {
.btn-block;
}
@@ -1124,7 +1139,6 @@ td.product,
> tr {
> td {
&.price,
&.unitprice,
&.qty,
&.subprice { padding: 35px 10px; }
}

View File

@@ -1,13 +1,13 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Cart"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-cart{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}]
]}
{/block}
{block name="main-content"}
@@ -16,6 +16,8 @@
<h1 id="main-label" class="page-header">{intl l="Your Cart"}</h1>
{nocache}
{ifloop rel="cartloop"}
<div class="btn-group checkout-progress">
<a href="#" role="button" class="btn btn-step active"><span class="step-nb">1</span> <span class="step-label">{intl l="Your Cart"}</span></a>
<a href="#" role="button" class="btn btn-step disabled"><span class="step-nb">2</span> <span class="step-label">{intl l="Billing and delivery"}</span></a>
@@ -53,9 +55,7 @@
</tr>
</thead>
<tbody>
{loop type="cart" name="cartloop"}
<tr>
<td class="image">
<a href="{$PRODUCT_URL}" class="thumbnail">
@@ -70,24 +70,26 @@
{/elseloop}
</td>
<td class="product" >
<h3 class="name"><a href="product-details.php">
Product #{$LOOP_COUNT}
<h3 class="name"><a href="{$URL}">
{$TITLE}
</a></h3>
<div class="product-options">
<dl class="dl-horizontal">
<dt>{intl l="Available"} :</dt>
{if $STOCK > 0}
<dd>{intl l="In Stock"}</dd>
{else}
<dd>{intl l="Out of Stock"}</dd>
{/if}
<dt>{intl l="No."}</dt>
<dd>{$REF}</dd>
{*<dt>Select Size</dt>
<dd>Large</dd>
<dt>Select Delivery Date</dt>
<dd>Jan 2, 2013</dd>
<dt>Additional Option</dt>
<dd>Option 1</dd>*}
{loop type="attribute_combination" name="product_options" product_sale_elements="$PRODUCT_SALE_ELEMENTS_ID"}
<dt>{$ATTRIBUTE_TITLE}</dt>
<dd>{$ATTRIBUTE_AVAILABILITY_TITLE}</dd>
{/loop}
</dl>
</div>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove">{intl l="Remove"}</a>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove"><i class="icon-trash"></i> {intl l="Remove"}</a>
</td>
<td class="unitprice">
{if $IS_PROMO == 1}
@@ -117,7 +119,6 @@
</tr>
{/loop}
</tbody>
<tfoot>
<tr >
@@ -135,40 +136,43 @@
<a href="{navigate to="index"}" role="button" class="btn btn-continue-shopping"><span>{intl l="Continue Shopping"}</span></a>
<a href="{url path="/order/delivery"}" class="btn btn-checkout">{intl l="Proceed checkout"}</a>
{/ifloop}
{elseloop rel="cartloop"}
<div class="cart-warning">
<strong>{intl l="Warning"}!</strong> {intl l="You have no items in your shopping cart."}
</div>
{/elseloop}
{/nocache}
</article>
{ifloop rel="product_upsell"}
<aside id="products-upsell" role="complementary" aria-labelledby="products-upsell-label">
<div class="products-heading">
<h3 id="products-upsell-label">{intl l="Upsell Products"}</h3>
</div>
<div class="products-content">
<ul class="products-grid product-col-<?php echo $product_upsell; ?> hover-effect">
<?php
// Product Parameters
$has_description = false; // Product without description
$has_btn = false; // Product without button (Add to Cart)
<ul class="products-grid product-col-5 hover-effect">
{loop name="product_upsell" type="product" promo="yes" limit="5"}
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="218" height="146"}
{/loop}
for ($count = 1; $count <= $product_upsell; $count++) { ?>
<li class="item">
<?php include('inc/inc-product.php') ?>
</li>
<?php } ?>
</ul>
</div>
</aside><!-- #products-upsell -->
{/ifloop}
</div>
{/block}
{block name="javascript-initialization"}
<script type="text/javascript">
jQuery(function($cart) {
<script type="text/javascript">
jQuery(function($cart) {
$cart('.js-update-quantity').on('change', function(e) {
var newQuantity = $cart(this).val();
$cart(this).parent().submit();
})
});
</script>
});
</script>
{/block}

View File

@@ -1,30 +1,24 @@
{extends file='layout.tpl'}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">You are here: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
{* Body Class *}
{block name="body-class"}page-category{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$sBreadcrumb = []}
{loop name="category_path" type="category-path" category="{category attr="id"}"}
{if $ID == {category attr="id"}}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active">
<span itemprop="title">{$TITLE}</span>
</li>
{else}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$URL}" itemprop="url"><span itemprop="title">{$TITLE}</span></a></li>
{/if}
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL nofilter}]}
{/loop}
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block}
{block name="main-content"}
<div class="main layout-col-2-left">
{$limit={$smarty.get.limit|default:8}}
{$product_page={$smarty.get.page|default:1}}
{$product_order={$smarty.get.order|default:'alpha'}}
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main">
{include file="includes/category-toolbar.html" toolbar="top" limit=$limit order=$product_order}
{include file="includes/toolbar.html" toolbar="top" limit=$limit order=$product_order}
<div id="category-products">
<div class="products-content">
<ul class="product-col-4">
@@ -34,7 +28,7 @@
</ul>
</div>
</div><!-- /#category-products -->
{include file="includes/category-toolbar.html" toolbar="bottom"}
{include file="includes/toolbar.html" toolbar="bottom"}
</article>
<aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar">

View File

@@ -0,0 +1,36 @@
{extends file="layout.tpl"}
{block name="no-return-functions"}
{/block}
{block name="body-class"}page-content{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{/block}
{block name="main-content"}
<div class="main layout-col-2-left" <!-- class="mainlayout-col-2-left -->">
<article class="col-main" role="main" aria-labelledby="main-label">
{loop name="blog.article" type="content" current="yes"}
<h1>{$TITLE}</h1>
<p class="chapo">
{$CHAPO}
</p>
<p>{$DESCRIPTION nofilter}</p>
{/loop}
</article>
<aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar">
{include file="includes/asides/articles.html"}
</aside>
</div><!-- /.layout -->
{/block}
{block name="after-javascript-include"}{/block}

View File

@@ -0,0 +1,16 @@
<section id="categories" class="block block-nav" role="navigation" aria-labelledby="categories-label">
<div class="block-heading"><h3 class="block-title" >{intl l="Related"}</h3></div>
<div class="block-content">
<nav class="nav-categories">
<ul id="category" class="accordion">
{loop name="current_article" type="content" current="yes"}
{assign var="current_id" value={$ID}}
{/loop}
{loop name="blog.article" type="content" current_folder="yes" exclude="$current_id"}
<li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
</ul>
</nav>
</div>
</section>

View File

@@ -0,0 +1,71 @@
{ifloop rel="cartloop"}
<li class="dropdown pull-right cart-not-empty">
<a href="{url path="/cart"}" rel="nofollow" class="cart">
{intl l="Cart"} <span class="badge">{cart attr="count_item"}</span>
</a>
<div class="dropdown-menu cart-content">
<form id="form-cart-mini" action="{url path="/order/delivery"}" method="post" role="form">
<table class="table table-cart-mini">
<colgroup>
<col width="70">
<col>
<col width="100">
</colgroup>
<tbody>
{assign "total_price" 0}
{loop type="cart" name="cartloop"}
<tr>
<td class="image">
{ifloop rel="product-image"}
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="60"}
<img src="{$IMAGE_URL}" alt="{$TITLE}">
{/loop}
{/ifloop}
</td>
<td class="product">
<h3 class="name" style="margin:0"><a href="{$URL}">
{$TITLE}
</a></h3>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove" data-tip="tooltip" data-title="Delete" data-original-title=""><i class="icon-trash"></i> <span>Remove</span></a>
</td>
<td class="unitprice text-center">
{if $IS_PROMO == 1}
{assign "real_price" $PROMO_TAXED_PRICE}
{else}
{assign "real_price" $TAXED_PRICE}
{/if}
<span class="qty">{$QUANTITY}</span> X <span class="price" style="font-size:1em;">{currency attr="symbol"}{$real_price}</span></div>
{assign "total_price" $total_price + ($QUANTITY * $real_price)}
</td>
</tr>
{/loop}
</tbody>
<tfoot>
<tr>
<td colspan="2" class="empty">
<a href="{url path="/cart"}" role="button" class="btn btn-default btn-sm"><span>{intl l="View Cart"}</span></a>
<button type="submit" name="checkout" class="btn btn-warning btn-sm"><span>{intl l="Checkout"}</span></button>
</td>
<td class="total">
<div class="total-price">
<span class="price">{currency attr="symbol"}{$total_price}</span>
</div>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</li>
{/ifloop}
{elseloop rel="cartloop"}
<li class="dropdown pull-right">
<a href="{url path="/cart"}" rel="nofollow" class="cart">
{intl l="Cart"} <span class="badge">0</span>
</a>
<div class="dropdown-menu cart-content">
<p>{intl l="You have no items in your shopping cart."}</p>
</div>
</li>
{/elseloop}

View File

@@ -1,5 +1,6 @@
<li class="item">
<article itemscope itemtype="http://schema.org/Product">
{assign var="hasSubmit" value = false}
<article itemscope itemtype="http://schema.org/Product">
<!-- Use the meta tag to specify content that is not visible on the page in any way -->
{loop name="brand.feature" type="feature" product=$ID title="brand"}
{loop name="brand.value" type="feature_value" feature=$ID product=$product_id}
@@ -55,11 +56,78 @@
{/if}
</div>
{if $hasBtn}
<div class="product-btn">
<button class="btn btn-cart">Add to cart</button>
{form name="thelia.cart.add" }
<form id="form-product-details" action="{url path="/cart/add" }" method="post" role="form">
{form_hidden_fields form=$form}
<input type="hidden" name="view" value="product">
<input type="hidden" name="product_id" value="{$ID}">
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
{form_field form=$form field='product_sale_elements_id'}
{if $default_product_sale_elements }
<input type="hidden" name="{$name}" value="{$default_product_sale_elements}" {$attr}>
{else}
{loop name="productSaleElements_promo" type="product_sale_elements" product="{$ID}" limit="1"}
<input type="hidden" name="{$name}" value="{$ID}" {$attr}>
{/loop}
{/if}
{/form_field}
{form_field form=$form field="product"}
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$ID}" {$attr} >
{/form_field}
<fieldset class="product-options hide">
{ifloop rel="stock"}
<div class="option">
<label for="options" class="option-heading">Options</label>
<div class="option-content">
<select name="options" class="form-control">
{loop name="stock" type="product_sale_elements" product="$ID" order="min_price"}
{if $LOOP_TOTAL == 1}
{assign var="hasSubmit" value = true}
{/if}
{loop name="combi" type="attribute_combination" product_sale_elements="$ID" order="alpha"}
<option value="{$ID}" data-quantity="{$QUANTITY}" data-price="{format_number number="{$BEST_TAXED_PRICE}"} {currency attr="symbol"}" data-old-price="{format_number number="{$TAXED_PRICE}"} {currency attr="symbol"}">{$ATTRIBUTE_AVAILABILITY_TITLE}</small></option>
{/loop}
{/loop}
</select>
</div>
</div>
{/ifloop}
</fieldset>
<fieldset class="product-cart form-inline">
{form_field form=$form field='quantity'}
<div class="form-group group-qty hide {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label for="{$label_attr.for}">{$label}</label>
<input type="number" name="{$name}" id="{$label_attr.for}" class="form-control" value="{$value|default:1}" min="0" required>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</article><!-- /product -->
{/form_field}
<div class="form-group group-btn">
</div>
<div>
<div class="product-btn">
{if $hasSubmit == true}
<button type="submit" class="btn btn-cart">{intl l="Add to cart"}</button>
{else}
<a href="{$URL}" class="btn btn-cart">{intl l="View product"}</a>
{/if}
</div>
</div>
</fieldset>
</form>
{/form}
</div>
</article><!-- /product -->
</li>

View File

@@ -6,11 +6,11 @@
<span class="limiter">
<label for="limit-top">{intl l="Show"}</label>
<select id="limit-top" name="limit">
<option value="{url path="{category attr="url"}" limit="4"}" {if $limit==4}selected{/if}>4</option>
<option value="{url path="{category attr="url"}" limit="8"}" {if $limit==8}selected{/if}>8</option>
<option value="{url path="{category attr="url"}" limit="12"}" {if $limit==12}selected{/if}>12</option>
<option value="{url path="{category attr="url"}" limit="50"}"{if $limit==50}selected{/if}>50</option>
<option value="{url path="{category attr="url"}" limit="9999999999"}" {if $limit==9999999999}selected{/if}>All</option>
<option value="{url path={navigate to="current"} limit="4"}" {if $limit==4}selected{/if}>4</option>
<option value="{url path={navigate to="current"} limit="8"}" {if $limit==8}selected{/if}>8</option>
<option value="{url path={navigate to="current"} limit="12"}" {if $limit==12}selected{/if}>12</option>
<option value="{url path={navigate to="current"} limit="50"}"{if $limit==50}selected{/if}>50</option>
<option value="{url path={navigate to="current"} limit="9999999999"}" {if $limit==9999999999}selected{/if}>All</option>
</select>
<span class="per-page">{intl l="per page"}</span>
</span><!-- /.limiter -->
@@ -19,10 +19,10 @@
<label for="sortby-top">{intl l="Sort By"}</label>
<select id="sortby-top" name="sortby">
{*<option value="{url path="{category attr="url"}" order="manual"}">{intl l="Position"}</option>*}
<option value="{url path="{category attr="url"}" limit=$limit order="alpha"}" {if $order=="alpha"}selected{/if}>{intl l="Name ascending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="alpha_reverse"}" {if $order=="alpha_reverse"}selected{/if}>{intl l="Name descending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="min_price"}" {if $order=="min_price"}selected{/if}>{intl l="Price ascending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="max_price"}" {if $order=="max_price"}selected{/if}>{intl l="Price descending"}</option>
<option value="{url path={navigate to="current"} limit=$limit order="alpha"}" {if $order=="alpha"}selected{/if}>{intl l="Name ascending"}</option>
<option value="{url path={navigate to="current"} limit=$limit order="alpha_reverse"}" {if $order=="alpha_reverse"}selected{/if}>{intl l="Name descending"}</option>
<option value="{url path={navigate to="current"} limit=$limit order="min_price"}" {if $order=="min_price"}selected{/if}>{intl l="Price ascending"}</option>
<option value="{url path={navigate to="current"} limit=$limit order="max_price"}" {if $order=="max_price"}selected{/if}>{intl l="Price descending"}</option>
{*<option value="{url path="{category attr="url"}" order="rating"}">{intl l="Rating"}</option>*}
</select>
</span><!-- /.sort-by -->
@@ -30,7 +30,7 @@
<span class="view-mode">
<span class="view-mode-label">{intl l="View as"}:</span>
<span class="view-mode-btn">
<a href="{url path="{navigate to="current"}" mode="grid"}" data-toggle="view" role="button" class="btn btn-grid"><i class="icon-grid"></i></a>
<a href="{url path="{navigate to="current"}" mode='grid'}" data-toggle="view" role="button" class="btn btn-grid"><i class="icon-grid"></i></a>
<a href="{url path="{navigate to="current"}" mode="list"}" data-toggle="view" role="button" class="btn btn-list "><i class="icon-list"></i></a>
</span>
</span><!-- /.view-mode -->

View File

@@ -1,5 +1,10 @@
{extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-home{/block}
{* Hide breadcrumb *}
{block name='breadcrumb'}{/block}
{block name="main-content"}
<section class="carousel-container">
@@ -25,7 +30,7 @@
<section id="products-new">
<div class="products-heading">
<h2>Latest <a href="#latest" class="btn-all">+ View All</a></h2>
<h2>{intl l="Latest"} <a href="{url path="/view_all" type="new"}" class="btn-all">{intl l="+ View All"}</a></h2>
</div>
<div class="products-content">
@@ -94,7 +99,7 @@
<section id="products-offer">
<div class="products-heading">
<h2>Offers <a href="#offer" class="btn-all">+ View All</a></h2>
<h2>{intl l="Offers"} <a href="{url path="/view_all" type="offers"}" class="btn-all">{intl l="+ View All"}</a></h2>
</div>
<div class="products-content">

View File

@@ -11,34 +11,39 @@
Author: Christophe Laffont
URL: http://www.thelia.net
-->
<!--[if lt IE 7 ]><html class="no-js oldie ie6" lang="fr"> <![endif]-->
<!--[if IE 7 ]><html class="no-js oldie ie7" lang="fr"> <![endif]-->
<!--[if IE 8 ]><html class="no-js oldie ie8" lang="fr"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="fr" class="no-js"> <!--<![endif]-->
{* paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither *}
<!--[if lt IE 7 ]><html class="no-js oldie ie6" lang="{lang attr="code"}"> <![endif]-->
<!--[if IE 7 ]><html class="no-js oldie ie7" lang="{lang attr="code"}"> <![endif]-->
<!--[if IE 8 ]><html class="no-js oldie ie8" lang="{lang attr="code"}"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="{lang attr="code"}" class="no-js"> <!--<![endif]-->
<head>
{* Test if javascript is enabled *}
<script>(function(H) { H.className=H.className.replace(/\bno-js\b/,'js') } )(document.documentElement);</script>
<meta charset="utf-8">
<title>{block name="page-title"}Thelia - E-commerce plateform{/block}</title>
<meta charset="utf-8">
{* Page Title *}
<title>{block name="page-title"}{strip}{if $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title} | {/foreach}{/if}{config key="company_name"}{/strip}{/block}</title>
{* Meta Tags *}
<meta name="description" content="">
<meta name="generator" content="THELIA V2">
<meta name="generator" content="{intl l='Thelia V2'}">
<meta name="robots" content="index,follow">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
{block name="meta"}{/block}
<!-- StyleSheet -->
{stylesheets file='assets/less/styles.less' filters='less,cssembed,cssrewrite'}
{* Stylesheets *}
{stylesheets file='assets/less/styles.less' filters='less,cssembed'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{debugbar_rendercss}
{block name="stylesheet"}{/block}
</head>
<body class="page-home" itemscope itemtype="http://schema.org/WebPage">
<body class="{block name="body-class"}{/block}" itemscope itemtype="http://schema.org/WebPage">
<!-- Accessibility -->
<a class="sr-only" href="#content">Skip to content</a>
<a class="sr-only" href="#content">{intl l="Skip to content"}</a>
<div class="page" role="document">
@@ -50,38 +55,63 @@ URL: http://www.thelia.net
<div class="navbar-header">
<!-- .navbar-toggle is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-main">
<span class="sr-only">Toggle navigation</span>
<span class="sr-only">{intl l="Toggle navigation"}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Thelia</a>
<a class="navbar-brand" href="{navigate to="index"}">{config key="company_name"}</a>
</div>
<!-- Place everything within .nav-collapse to hide it until above 768px -->
<nav class="navbar-collapse collapse nav-main" role="navigation" aria-label="Main Navigation">
<nav class="navbar-collapse collapse nav-main" role="navigation" aria-label="{intl l="Main Navigation"}">
{nocache}
<ul class="nav navbar-nav navbar-cart navbar-right">
{loop type="auth" name="customer_info_block" roles="CUSTOMER" context="front"}
<li><a href="{url path="/logout"}" class="logout">{intl l="Log out!"}</a></li>
<li><a href="{url path="/account"}" class="account">{intl l="My Account"}</a></li>
{/loop}
{elseloop rel="customer_info_block"}
<li><a href="{url path="/register"}" class="register">{intl l="Register!"}</a></li>
<li class="dropdown">
<a href="{url path="/login"}" class="login">{intl l="Log In!"}</a>
<div class="dropdown-menu">
{form name="thelia.customer.login"}
<form id="form-login-mini" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form}>
{form_hidden_fields form=$form}
{form_field form=$form field="email"}
<div class="form-group group-email">
<label for="{$label_attr.for}-mini">Email address</label>
<input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required>
</div>
{/form_field}
{form_field form=$form field="password"}
<div class="form-group group-password">
<label for="{$label_attr.for}-mini">Password</label>
<input type="password" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required>
</div>
{/form_field}
{form_field form=$form field="account"}
<input type="hidden" name="{$name}" value="1">
{/form_field}
<div class="group-btn">
<button type="submit" class="btn btn-login-mini">{intl l="Sign In"}</button>
<a href="{url path="/register"}" class="btn btn-register-mini">{intl l="Register"}</a>
</div>
</form>
{/form}
</div>
</li>
{/elseloop}
{include file="includes/mini-cart.html" nocache}
</ul>
{/nocache}
<ul class="nav navbar-nav navbar-categories">
<li class="active"><a href="{url path="/"}" class="home" tabindex="-1">Home</a></li>
<li><a href="{navigate to="index"}" class="home">{intl l="Home"}</a></li>
{loop type="category" name="category.navigation" parent="0"}
<li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
</ul>
<ul class="nav navbar-nav navbar-cart navbar-right">
{loop type="auth" name="customer_info_block" roles="CUSTOMER" context="front"}
<li><a href="{url path="/logout"}" class="register">{intl l="Log out!"}</a></li>
<li><a href="{url path="/customer/account"}" class="login">{intl l="My Account"}</a></li>
{/loop}
{elseloop rel="customer_info_block"}
<li><a href="{url path="/register"}" class="register">{intl l="Register"}!</a></li>
<li><a href="{url path="/login"}" class="login">{intl l="Log In!"}</a></li>
{/elseloop}
<li class="dropdown">
<a href="{url path="/cart"}" class="dropdown-toggle cart" {*data-toggle="dropdown"*}>
Cart <span class="badge">{cart attr="count_item"}</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
@@ -90,28 +120,28 @@ URL: http://www.thelia.net
<header class="container" role="banner">
<div class="header">
<h1 class="logo">
<a href="{url path="/"}" class="Thelia * Since 2006 *">
{images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="Thelia">{/images}
<a href="{navigate to="index"}" title="{config key="company_name"}">
{images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="{config key="company_name"}">{/images}
</a>
</h1>
<div class="language-container">
<div class="search-container">
<form id="form-search" action="search.html" method="get" role="search" aria-labelledby="search-label">
<label id="search-label" for="q">Search a product</label>
<form id="form-search" action="{url path="/search"}" method="get" role="search" aria-labelledby="search-label">
<label id="search-label" for="q">{intl l="Search a product"}</label>
<div class="input-group">
<input type="search" name="q" id="q" placeholder="Search..." class="form-control" aria-required="true" required pattern=". { 2,}" title="Minmimum 2 characters.">
<input type="search" name="q" id="q" placeholder="{intl l="Search..."}" class="form-control" autocomplete="off" aria-required="true" required pattern=".{ldelim}2,{rdelim}" title="{intl l="Minimum 2 characters."}">
<div class="input-group-btn">
<button type="submit" class="btn btn-search"><i class="icon-search"></i> <span>Search</span></button>
<button type="submit" class="btn btn-search"><i class="icon-search"></i> <span>{intl l="Search"}</span></button>
</div>
</div>
</form>
</div>
<div class="language-switch" aria-labelledby="language-label">
<span id="language-label" class="dropdown-label">Language:</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="language.html">{lang attr="title"}</a>
<span id="language-label" class="dropdown-label">{intl l="Language:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/language"}">{lang attr="title"}</a>
<ul class="select dropdown-menu">
{loop type="lang" name="lang_available" exclude="{lang attr="id"}"}
<li><a href="?lang={$CODE}">{$TITLE}</a></li>
@@ -120,8 +150,8 @@ URL: http://www.thelia.net
</div>
<div class="currency-switch" aria-labelledby="currency-label">
<span id="currency-label" class="dropdown-label">{intl l="Currency"}:</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="currency.html">{currency attr="code"}</a>
<span id="currency-label" class="dropdown-label">{intl l="Currency:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/currency"}">{currency attr="code"}</a>
<ul class="select dropdown-menu">
{loop type="currency" name="currency_available" exclude="{currency attr="id"}" }
<li><a href="?currency={$ISOCODE}">{$SYMBOL} - {$NAME}</a></li>
@@ -137,7 +167,7 @@ URL: http://www.thelia.net
<main class="main-container" role="main">
<div class="container">
{block name="breadcrumb"}{/block}
{block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block}
{block name="main-content"}{/block}
</div><!-- /.container -->
</main><!-- /.main-container -->
@@ -170,26 +200,23 @@ URL: http://www.thelia.net
<section class="block block-links">
<div class="block-heading"><h3 class="block-title">Latest articles</h3></div>
<div class="block-content">
{ifloop rel="blog.articles"}
<ul>
{loop type="content" name="blog.articles" folder="1" limit="3"}
<li>
<a href="#">
<h4 class="block-subtitle">Heading</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
</a>
</li>
<li>
<a href="#">
<h4 class="block-subtitle">Heading</h4>
<p>Lorem ipsum dolor sit amet...</p>
</a>
</li>
<li>
<a href="#">
<h4 class="block-subtitle">Heading</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
<a href="{$URL}">
<h4 class="block-subtitle">{$TITLE}</h4>
<p>{$CHAPO}</p>
</a>
</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="blog.articles"}
<ul>
<li>{intl l="No articles currently"}</li>
</ul>
{/elseloop}
</div>
</section>
</div>
@@ -198,13 +225,12 @@ URL: http://www.thelia.net
<div class="block-heading"><h3 class="block-title">Usefull links</h3></div>
<div class="block-content">
<ul>
<li class="active"><a href="#" tabindex="-1">About Us </a></li>
<li><a href="#">Delivery & Returns</a></li>
<li><a href="#">Terms & Conditions </a></li>
<li><a href="contact.html">Contact Us</a></li>
{loop name="footer_links" type="content" folder="2"}
<li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
<li><a href="{url path="/login"}">Login</a></li>
<li><a href="{url path="/register"}">Register</a></li>
<li><a href="checkout.html">Checkout</a></li>
<li><a href="{url path="/order/delivery"}">Checkout</a></li>
</ul>
</div>
</section>
@@ -268,15 +294,15 @@ URL: http://www.thelia.net
</section>
<section class="block block-newsletter">
<div class="block-heading"><h3 class="block-title">Newsletter</h3></div>
<div class="block-heading"><h3 class="block-title">{intl l="Newsletter"}</h3></div>
<div class="block-content">
<p id="newletter-describe">Sign up to receive our latest news.</p>
<form id="form-newsletter" action="" method="post" role="form">
<p id="newletter-describe">{intl l="Sign up to receive our latest news."}</p>
<form id="form-newsletter" action="{url path="/newsletter"}" method="post" role="form">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" name="email" id="email" class="form-control" placeholder="Your email address" aria-describedby="newletter-describe" aria-required="true" required autocomplete="off">
<label for="email">{intl l="Email address"}</label>
<input type="email" name="email" id="email" class="form-control" placeholder="{intl l="Your email address"}" aria-describedby="newletter-describe" aria-required="true" required autocomplete="off">
</div>
<button type="submit" class="btn btn-subscribe">Subscribe</button>
<button type="submit" class="btn btn-subscribe">{intl l="Subscribe"}</button>
</form>
</div>
</section>
@@ -286,7 +312,7 @@ URL: http://www.thelia.net
<section class="block block-contact" itemscope itemtype="http://schema.org/Organization">
<div class="block-heading"><h3 class="block-title">Contact Us</h3></div>
<div class="block-content">
<meta itemprop="name" content="Thelia V2">
<meta itemprop="name" content="{config key="company_name"}">
<ul>
<li class="contact-address">
<address class="adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
@@ -299,7 +325,7 @@ URL: http://www.thelia.net
<span class="tel" itemprop="telephone">+33 04 44 05 31 00</span>
</li>
<li class="contact-email">
<a href="mailto:demo@thelia.net" class="email" itemprop="email">info@thelia.net</a>
{mailto address="info@thelia.net" encode="hex" extra='class="email" itemprop="email"'}
</li>
</ul>
</div>
@@ -315,8 +341,9 @@ URL: http://www.thelia.net
<div class="info">
<nav class="nav-footer" role="navigation">
<ul>
<li class="active"><a href="#" tabindex="-1">About Us </a></li>
<li><a href="#">Delivery & Returns</a></li>
{loop name="footer_links" type="content" folder="2"}
<li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
<li><a href="#">Site Map</a></li>
<li><a href="#">Terms & Conditions</a></li>
<li><a href="#">Contact Us</a></li>
@@ -344,59 +371,28 @@ URL: http://www.thelia.net
}
</script>
<!-- Bootstrap -->
{javascripts file='assets/js/bootstrap/affix.js'}
{javascripts file='assets/js/bootstrap/bootstrap.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/tooltip.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/popover.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/tab.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/scrollspy.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/transition.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/alert.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/button.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/carousel.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/collapse.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/dropdown.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/modal.js'}
{javascripts file='assets/js/plugins/bootbox/bootbox.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{block name="after-javascript-include"}{/block}
{block name="javascript-initialization"}{/block}
<!-- Custom scripts -->
{javascripts file='assets/js/script.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{debugbar_renderjs}
{debugbar_renderresult}
{* HTML5 shim, for IE6-8 support of HTML5 elements *}
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
{block name="after-javascript-include"}{/block}
{block name="javascript-initialization"}{/block}
</body>
</html>

View File

@@ -1,62 +1,63 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Login"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-login{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Login"}, 'url'=>{url path="/login"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Login"}</h1>
{form name="thelia.customer.login"}
<form id="form-login" action="{url path="/customer/login"}" method="post" role="form" {form_enctype form=$form}>
<form id="form-login" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form}>
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}"> {* the url the user is redirected to on login success *}
{/form_field}
{form_field form=$form field='error_message'}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}"> {* the url the user is redirected to on login success *}
{/form_field}
{form_hidden_fields form=$form}
<fieldset>
{form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{/if} ">
<div class="form-group group-email{if $error} has-error{/if}">
<label for="{$label_attr.for}">{$label}</label>
<div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" {$attr} aria-required="true" autofocus required>
<input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" {$attr} {if $required}aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
{if $error}
<span class="help-block"><span class="icon-remove"></span> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{/if}
</div>
</div>
{/form_field}
<fieldset>
{form_field form=$form field="account"}
<legend>{intl l="Do you have an account?"}</legend>
<div class="radio radio-account0" >
<label for="account0">
<input type="radio" name="account" id="account0" data-toggle="password" value="0" > {intl l="No, I am a new customer."}
</label>
</div>
<div class="radio radio-account1">
<label for="account1">
<input type="radio" name="account" id="account1" data-toggle="password" value="1" checked> {intl l="Yes, I have a password :"}
{foreach $choices as $choice}
<div class="radio radio-account{$choice->value}">
<label for="{$label_attr.for}{$choice->value}">
<input type="radio" name="{$name}" id="{$label_attr.for}{$choice->value}" data-toggle="password" value="{$choice->value}"{if $value === {$choice->value}} checked{/if}> {$choice->label}
</label>
</div>
{/foreach}
{/form_field}
{form_field form=$form field="password"}
<div class="form-group group-password {if $error}has-error{/if} ">
<div class="form-group group-password{if $error} has-error{/if}">
<label for="{$label_attr.for}" class="sr-only">{$label}</label>
<div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if !isset($error_focus)} autofocus{/if}>
{if $error}
<span class="help-block"><span class="icon-remove"></span> {$message}</span>
{/if}
@@ -67,7 +68,7 @@
</fieldset>
<div class="group-btn">
<a href="{url path="/password"}" class="forgot-password">{intl l="Forgot your Password ?"}</a>
<a href="{url path="/password"}" data-toggle="confirmation" class="forgot-password">{intl l="Forgot your Password?"}</a>
<button type="submit" class="btn btn-login">{intl l="Next"}</button>
</div>
</form>

View File

@@ -0,0 +1,16 @@
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here:"}</strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
{foreach $breadcrumbs as $breadcrumb}
{if $breadcrumb.title}
{if $breadcrumb@last}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{$breadcrumb.title}</span></li>
{else}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$breadcrumb.url|default:'#' nofilter}" title="{$breadcrumb.title}" itemprop="url"><span itemprop="title">{$breadcrumb.title}</span></a></li>
{/if}
{/if}
{/foreach}
</ul>
</nav><!-- /.nav-breadcrumb -->

View File

@@ -5,17 +5,18 @@
{check_cart_not_empty}
{/block}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Billing and delivery"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-order-delivery{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
['title' => {intl l="Billing and delivery"}, 'url'=>{url path="/order/delivery"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article id="cart" class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -6,17 +6,18 @@
{check_valid_delivery}
{/block}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="My order"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-order-invoice{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
['title' => {intl l="My order"}, 'url'=>{url path="/order/invoice"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -1,16 +1,17 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Secure Payment"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-order-payment{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
['title' => {intl l="Secure Payment"}, 'url'=>{url path="/order/pay"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main clearfix" role="main" aria-labelledby="main-label">

View File

@@ -1,15 +1,16 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"} </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Password"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{* Body Class *}
{block name="body-class"}page-password{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Password"}, 'url'=>{url path="/password"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -1,20 +1,20 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
{* Body Class *}
{block name="body-class"}page-product{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$sBreadcrumb = []}
{loop type="product" name="product_breadcrumb" id="{product attr="id"}"}
{loop name="category_path" type="category-path" category="{$DEFAULT_CATEGORY}"}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$URL}" itemprop="url"><span itemprop="title">{$TITLE}</span></a></li>
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
{/loop}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{$TITLE}</span></li>
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
{/loop}
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block}
{block name="main-content"}
<div class="main">
{loop name="product.details" type="product" id="{product attr="id"}"}
@@ -26,8 +26,8 @@
<meta itemprop="brand" content="{$TITLE}">
{/loop}
{/loop}
{loop name="isbn.feature" type="feature" product=$ID title="isbn"}
{loop name="brand.value" type="feature_value" feature=$ID product=$product_id}
{loop name="brand.feature" type="feature" product="{$ID}" title="isbn"}
{loop name="brand.value" type="feature_value" feature="{$ID}" product=$product_id}
<meta itemprop="productID" content="isbn:{$TITLE}">
{/loop}
{/loop}
@@ -88,9 +88,32 @@
</div>
</div>
{loop name="stock_meta" type="product_sale_elements" product="$ID"}
{loop name="combi_meta" type="attribute_combination" product_sale_elements="$ID"}
{if $LOOP_COUNT == 0}
{if $QUANTITY == 0}
{assign var="current_stock_class" value = "out-of-stock"}
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
{else}
{assign var="current_stock_class" value = "out-of-stock"}
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
{/if}
{/if}
{/loop}
{/loop}
<div class="product-price" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<div class="availability"><span class="availibity-label">{intl l="Availability"}: </span><span itemprop="availability" href="http://schema.org/InStock" class="in-stock">In stock</span></div>
<div class="availability">
<span class="availibity-label">{intl l="Availability"}: </span>
<span itemprop="availability" href="{$current_stock_href}" class="{$current_stock_class}" id="stockInformations">
<span class="in">{intl l='In stock'}</span><span class="out">{intl l='Out of stock'}</span>
</span>
</div>
<div class="price-container">
{loop type="category" name="category_tag" id=$DEFAULT_CATEGORY}
@@ -98,14 +121,6 @@
{/loop}
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition -->
<meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. -->
<link itemprop="availability" href="http://schema.org/InStock" content="in_stock" />
<!-- List of availibility :
out_of_stock : http://schema.org/OutOfStock
in_stock : http://schema.org/InStock
instore_only : http://schema.org/InStoreOnly
preorder : http://schema.org/PreOrder
online_only : http://schema.org/OnlineOnly
-->
{if $IS_PROMO }
{loop name="productSaleElements_promo" type="product_sale_elements" product="{$ID}" limit="1" order="min_price"}
{assign var="default_product_sale_elements" value="$ID"}
@@ -138,34 +153,22 @@
{form_field form=$form field="product"}
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$ID}" {$attr} >
{/form_field}
<fieldset class="product-options">
<div class="option option-color">
<label for="option-color" class="option-heading">Show</label>
{ifloop rel="stock"}
<div class="option">
<label for="options" class="option-heading">Options</label>
<div class="option-content">
<select id="option-color" name="option-color" class="form-control">
<option value="0">Blue</option>
<option value="1">Red</option>
<option value="2">Purple</option>
<select name="options" class="form-control">
{loop name="stock" type="product_sale_elements" product="$ID" order="min_price"}
{loop name="combi" type="attribute_combination" product_sale_elements="$ID" order="alpha"}
<option value="{$ID}" data-quantity="{$QUANTITY}" data-price="{format_number number="{$BEST_TAXED_PRICE}"} {currency attr="symbol"}" data-old-price="{format_number number="{$TAXED_PRICE}"} {currency attr="symbol"}">{$ATTRIBUTE_AVAILABILITY_TITLE}</small></option>
{/loop}
{/loop}
</select>
</div>
</div>
<div class="option option-size">
<fieldset>
<legend class="option-heading">Size</legend>
<div class="option-content">
<label class="checkbox-inline" for="size1">
<input type="checkbox" name="size1" id="size1" value="1"> Large
</label>
<label class="checkbox-inline" for="size2">
<input type="checkbox" name="size2" id="size2" value="2"> Medium
</label>
<label class="checkbox-inline" for="size3">
<input type="checkbox" name="size3" id="size3" value="3"> Small
</label>
</div>
</fieldset>
</div>
{/ifloop}
</fieldset>
<fieldset class="product-cart form-inline">
{form_field form=$form field='quantity'}
@@ -201,7 +204,8 @@
{ifloop rel="feature_value_info"}
<ul>
{loop name="feature_info" type="feature" product="{$ID}"}
<li> <strong>{$TITLE}</strong> :
<li>
<strong>{$TITLE}</strong> :
{loop name="feature_value_info" type="feature_value" feature="{$ID}" product="{product attr="id"}"}
{$TITLE}
{/loop}

View File

@@ -1,15 +1,12 @@
{extends file="layout.tpl"}
{block name="breadcrumb"}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Register"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block}
{* Body Class *}
{block name="body-class"}page-register{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [['title' => {intl l="Register"}, 'url'=>{url path="/register"}]]}
{/block}
{block name="main-content"}
<div class="main">
@@ -18,13 +15,13 @@
<h1 id="main-label" class="page-header">{intl l="Create New Account"}</h1>
{form name="thelia.customer.creation"}
<form id="form-register" class="form-horizontal" action="{url path="/customer/create"}" method="post" role="form">
<form id="form-register" class="form-horizontal" action="{url path="/register"}" method="post" role="form">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on registration success *}
{/form_field}
{form_field form=$form field='error_message'}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" /> {* the url the user is redirected to on login success *}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" />
{/form_field}
{form_hidden_fields form=$form}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
@@ -36,9 +33,9 @@
<div class="panel-body">
{form_field form=$form field="title"}
<div class="form-group group-title {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required autofocus>
<select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
<option value="">-- {intl l="Select Title"} --</option>
{loop type="title" name="country.list"}
<option value="{$ID}" {if $value == $ID}selected{/if} >{$LONG}</option>
@@ -46,6 +43,9 @@
</select>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -54,11 +54,12 @@
{/form_field}
{form_field form=$form field="firstname"}
<div class="form-group group-firstname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" required>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -67,11 +68,12 @@
{/form_field}
{form_field form=$form field="lastname"}
<div class="form-group group-lastname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" autofocus required>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Doe" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -80,12 +82,13 @@
{/form_field}
{form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" required value="{$smarty.get.email|default:$value}">
<input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" value="{$smarty.get.email|default:$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -94,11 +97,12 @@
{/form_field}
{form_field form=$form field="phone"}
<div class="form-group group-phone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -107,11 +111,12 @@
{/form_field}
{form_field form=$form field="cellphone"}
<div class="form-group group-cellphone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -129,11 +134,12 @@
<div class="panel-body">
{form_field form=$form field="company"}
<div class="form-group group-company {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Thelia" value="{$value}" autofocus>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Google" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -143,11 +149,12 @@
{form_field form=$form field="address1"}
<div class="form-group group-address1 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="{$label}" value="{$value}" autofocus required>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="76 Ninth Avenue" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -157,11 +164,12 @@
{form_field form=$form field="address2"}
<div class="form-group group-address2 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -171,11 +179,12 @@
{form_field form=$form field="city"}
<div class="form-group group-city {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="New York" value="{$value}" autofocus required>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="New York" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -185,11 +194,12 @@
{form_field form=$form field="zipcode"}
<div class="form-group group-zip {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="H2T 2V6" value="{$value}" autofocus required>
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="NY 10011" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -199,9 +209,9 @@
{form_field form=$form field="country"}
<div class="form-group group-country {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required>
<select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
<option value="">-- {intl l="Select Country"} --</option>
{loop type="country" name="country.list"}
<option value="{$ID}"
@@ -216,6 +226,7 @@
</select>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -232,11 +243,12 @@
<div class="panel-body">
{form_field form=$form field="password"}
<div class="form-group group-password {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" required autocomplete="off">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -246,11 +258,12 @@
{form_field form=$form field="password_confirm"}
<div class="form-group group-password_confirm {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label>
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" required autocomplete="off">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
@@ -260,19 +273,24 @@
</div>
</fieldset>
<div class="form-group group-agreed">
{form_field form=$form field="agreed"}
<div class="form-group group-agreed{if $error} has-error{/if}">
<div class="control-input">
<div class="checkbox">
<label class="control-label" for="agreed">
<input type="checkbox" name="agreed" id="agreed" value="1" required> I've read and agreed on <a href="#">Terms &amp; Conditions</a>.
<label class="control-label" for="{$label_attr.for}">
<input type="checkbox" name="{$name}" id="{$label_attr.for}" value="{$value}"{if $checked} checked{/if} {if $required} aria-required="true" required{/if}>I've read and agreed on <a href="#">Terms &amp; Conditions</a></a>.
</label>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{/if}
</div>
</div>
</div><!--/.form-group-->
{/form_field}
<div class="form-group group-btn">
<div class="control-btn">
<button type="submit" class="btn btn-register">Sign in</button>
<button type="submit" class="btn btn-register">{intl l="Sign in"}</button>
</div>
</div><!--/.form-group-->
</form>

View File

@@ -0,0 +1,47 @@
{extends file="layout.tpl"}
{block name="body-class"}page-search{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Search"}, 'url'=>{url path="/search"}]
]}
{/block}
{block name="main-content"}
<div class="main">
{$limit={$smarty.get.limit|default:8}}
{$product_page={$smarty.get.page|default:1}}
{$product_order={$smarty.get.order|default:'alpha'}}
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Search Result for"} <small>{$smarty.get.q}</small></h1>
{include file="includes/toolbar.html" toolbar="top" limit=$limit order=$product_order}
<div id="category-products">
<div class="products-content">
{ifloop rel="product_list"}
<ul class="product-col-3">
{loop type="product" name="product_list" title="{$smarty.get.q}" limit=$limit page=$product_page order=$product_order}
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="218" height="146"}
{assign "products_count" $LOOP_TOTAL}
{/loop}
</ul>
{/ifloop}
{elseloop rel="product_list"}
<h2 class="text-center">{intl l="No results found"} </h2>
{/elseloop}
</div>
</div><!-- /#category-products -->
{ifloop rel="product_list"}
{include file="includes/toolbar.html" toolbar="bottom"}
{/ifloop}
</article>
</div><!-- /.layout -->
{/block}
{block name="after-javascript-include"}{/block}

View File

@@ -0,0 +1,58 @@
{extends file="layout.tpl"}
{block name="body-class"}page-view-all{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="View all"}, 'url'=>{url path="/view_all"}]
]}
{/block}
{block name="main-content"}
<div class="main">
{$limit={$smarty.get.limit|default:8}}
{$product_page={$smarty.get.page|default:1}}
{$product_order={$smarty.get.order|default:'alpha'}}
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main" aria-labelledby="main-label">
{if $smarty.get.type == "new"}
<h1 id="main-label" class="page-header">{intl l="View all"} {$smarty.get.type} {intl l="products"}</h1>
{else}
<h1 id="main-label" class="page-header">{intl l="View all"} {intl l="offers"}</h1>
{/if}
{include file="includes/toolbar.html" toolbar="top" limit=$limit order=$product_order}
<div id="category-products">
<div class="products-content">
{ifloop rel="product_list"}
<ul class="product-col-3">
{if $smarty.get.type == "new"}
{loop type="product" name="product_list" limit=$limit page=$product_page order=$product_order}
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="700" height="320"}
{/loop}
{else}
{loop type="product" name="product_list" promo="yes" limit=$limit page=$product_page order=$product_order}
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="700" height="320"}
{/loop}
{/if}
</ul>
{/ifloop}
{elseloop rel="product_list"}
<h2 class="text-center">{intl l="No results found"} </h2>
{/elseloop}
</div>
</div><!-- /#category-products -->
{ifloop rel="product_list"}
{include file="includes/toolbar.html" toolbar="bottom"}
{/ifloop}
</article>
</div><!-- /.layout -->
{/block}
{block name="after-javascript-include"}{/block}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More