diff --git a/.gitignore b/.gitignore index ffacc2af94..c1315449fe 100755 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ composer.phar /app/config/*/session.php /app/config/*/database.php /app/config/*/app.php +/app/config/*/ldap.php public/packages/* public/uploads/models/* public/uploads/avatars/* @@ -25,10 +26,6 @@ public/uploads/logo.png public/assets/.siteflow app/config/local/session.php .couscous +app/storage/dumps/* tests/_support/_generated/* tests/_data/scenarios -nbproject/* -app/config/local/ldap.php -app/storage/dumps/* -app/config/packages/schickling/backup/config.php -app/config/app.backup.php diff --git a/app/config/version.php b/app/config/version.php index ccae3f3627..f5eb33330b 100644 --- a/app/config/version.php +++ b/app/config/version.php @@ -1,5 +1,5 @@ 'v2.0-175', - 'hash_version' => 'v2.0-175-gd0aab3e', + 'app_version' => 'v2.0-326', + 'hash_version' => 'v2.0-326-g1bdd588', ); \ No newline at end of file diff --git a/app/controllers/AuthController.php b/app/controllers/AuthController.php index c4a300e770..4121faa042 100755 --- a/app/controllers/AuthController.php +++ b/app/controllers/AuthController.php @@ -45,7 +45,7 @@ class AuthController extends BaseController if ($connection) { // binding to ldap server $ldapbind = ldap_bind($connection, $ldaprdn, $ldappass); - if ( ($results = @ldap_search($connection, $baseDn, $filterQuery)) !==false ) { + if ( ($results = @ldap_search($connection, $baseDn, $filterQuery)) != false ) { $entry = ldap_first_entry($connection, $results); if ( ($userDn = @ldap_get_dn($connection, $entry)) !== false ) { if( ($isBound = ldap_bind($connection, $userDn, $password)) == "true") { diff --git a/app/controllers/admin/AccessoriesController.php b/app/controllers/admin/AccessoriesController.php index b1f0a60c25..2d6d25b05c 100755 --- a/app/controllers/admin/AccessoriesController.php +++ b/app/controllers/admin/AccessoriesController.php @@ -68,6 +68,20 @@ class AccessoriesController extends AdminController // Update the accessory data $accessory->name = e(Input::get('name')); $accessory->category_id = e(Input::get('category_id')); + $accessory->order_number = e(Input::get('order_number')); + + if (e(Input::get('purchase_date')) == '') { + $accessory->purchase_date = NULL; + } else { + $accessory->purchase_date = e(Input::get('purchase_date')); + } + + if (e(Input::get('purchase_cost')) == '0.00') { + $accessory->purchase_cost = NULL; + } else { + $accessory->purchase_cost = ParseFloat(e(Input::get('purchase_cost'))); + } + $accessory->qty = e(Input::get('qty')); $accessory->user_id = Sentry::getId(); @@ -136,6 +150,20 @@ class AccessoriesController extends AdminController // Update the accessory data $accessory->name = e(Input::get('name')); $accessory->category_id = e(Input::get('category_id')); + $accessory->order_number = e(Input::get('order_number')); + + if (e(Input::get('purchase_date')) == '') { + $accessory->purchase_date = NULL; + } else { + $accessory->purchase_date = e(Input::get('purchase_date')); + } + + if (e(Input::get('purchase_cost')) == '0.00') { + $accessory->purchase_cost = NULL; + } else { + $accessory->purchase_cost = ParseFloat(e(Input::get('purchase_cost'))); + } + $accessory->qty = e(Input::get('qty')); // Was the accessory created? @@ -466,55 +494,76 @@ class AccessoriesController extends AdminController public function getDatatable() { $accessories = Accessory::with('category') - ->whereNull('deleted_at') - ->orderBy('created_at', 'DESC'); + ->whereNull('deleted_at'); - $accessories = $accessories->get(); + if (Input::has('search')) { + $accessories = $accessories->TextSearch(Input::get('search')); + } - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions',function($accessories) - { - return 'numRemaining() > 0 ) ? '' : ' disabled').'>'.Lang::get('general.checkout').''; - }); + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } - return Datatable::collection($accessories) - ->addColumn('category',function($accessories) - { - return $accessories->category->name; - }) - ->addColumn('name',function($accessories) - { - return link_to('admin/accessories/'.$accessories->id.'/view', $accessories->name); - }) - ->addColumn('qty',function($accessories) - { - return $accessories->qty; - }) - ->addColumn('numRemaining',function($accessories) - { - return $accessories->numRemaining(); - }) - ->addColumn($actions) - ->searchColumns('category','name','qty','numRemaining','actions') - ->orderColumns('category','name','qty','numRemaining','actions') - ->make(); + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + + $allowed_columns = ['name','order_number','purchase_date','purchase_cost']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $accessories = $accessories->orderBy($sort, $order); + + $accessCount = $accessories->count(); + $accessories = $accessories->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach ($accessories as $accessory) { + $actions = 'numRemaining() > 0 ) ? '' : ' disabled').'>'.Lang::get('general.checkout').''; + + $rows[] = array( + 'name' => link_to('admin/accessories/'.$accessory->id.'/view', $accessory->name), + 'category' => $accessory->category->name, + 'qty' => $accessory->qty, + 'order_number' => $accessory->order_number, + 'purchase_date' => $accessory->purchase_date, + 'purchase_cost' => $accessory->purchase_cost, + 'numRemaining' => $accessory->numRemaining(), + 'actions' => $actions + ); + } + + $data = array('total'=>$accessCount, 'rows'=>$rows); + + return $data; } public function getDataView($accessoryID) { $accessory = Accessory::find($accessoryID); $accessory_users = $accessory->users; + $count = $accessory_users->count(); - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions',function($accessory_users){ - return 'Checkin'; - }); + $rows = array(); - return Datatable::collection($accessory_users) - ->addColumn('name',function($accessory_users) - { - return link_to('/admin/users/'.$accessory_users->id.'/view', $accessory_users->fullName()); - }) - ->addColumn($actions) - ->make(); + foreach ($accessory_users as $user) { + $actions = 'Checkin'; + + $rows[] = array( + 'name' => link_to('/admin/users/'.$user->id.'/view', $user->fullName()), + 'actions' => $actions + ); + } + + $data = array('total'=>$count, 'rows'=>$rows); + + return $data; } } diff --git a/app/controllers/admin/AssetMaintenancesController.php b/app/controllers/admin/AssetMaintenancesController.php index 846b8ff153..85147a24b1 100644 --- a/app/controllers/admin/AssetMaintenancesController.php +++ b/app/controllers/admin/AssetMaintenancesController.php @@ -45,71 +45,63 @@ * @author Vincent Sposato * @version v1.0 */ - public function getDatatable() - { - $assetMaintenances = AssetMaintenance::orderBy( 'created_at', 'DESC' ) - ->get(); + public function getDatatable() + { + $maintenances = AssetMaintenance::with('asset','supplier') + ->whereNull('deleted_at'); - $actions = new \Chumper\Datatable\Columns\FunctionColumn( 'actions', function ( $assetMaintenances ) { + if (Input::has('search')) { + $maintenances = $maintenances->TextSearch(e(Input::get('search'))); + } - return ''; - } ); + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } - return Datatable::collection( $assetMaintenances ) - ->addColumn( 'asset', function ( $assetMaintenances ) { + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } - return link_to( '/hardware/' . $assetMaintenances->asset_id . '/view', - mb_strimwidth( $assetMaintenances->asset->name, 0, 50, "..." ) ); - } ) - ->addColumn( 'supplier', function ( $assetMaintenances ) { + $allowed_columns = ['id','title','asset_maintenance_time','asset_maintenance_type','cost','start_date','completion_date','notes']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; - return link_to( '/admin/settings/suppliers/' . $assetMaintenances->supplier_id - . '/view', - mb_strimwidth( $assetMaintenances->supplier->name, 0, 50, "..." ) ); - } ) - ->addColumn( 'asset_maintenance_type', function ( $assetMaintenances ) { + $maintenances->orderBy($sort, $order); - return $assetMaintenances->asset_maintenance_type; - } ) - ->addColumn( 'title', function ( $assetMaintenances ) { + $maintenancesCount = $maintenances->count(); + $maintenances = $maintenances->skip($offset)->take($limit)->get(); - return link_to( '/admin/asset_maintenances/' . $assetMaintenances->id . '/view', - mb_strimwidth( $assetMaintenances->title, 0, 50, "..." ) ); - } ) - ->addColumn( 'start_date', function ( $assetMaintenances ) { + $rows = array(); - return $assetMaintenances->start_date; - } ) - ->addColumn( 'completion_date', function ( $assetMaintenances ) { + foreach($maintenances as $maintenance) { - return $assetMaintenances->completion_date; - } ) - ->addColumn( 'asset_maintenance_time', function ( $assetMaintenances ) { + $actions = ''; - if (is_null( $assetMaintenances->asset_maintenance_time )) { - $assetMaintenances->asset_maintenance_time = Carbon::now() - ->diffInDays( Carbon::parse( $assetMaintenances->start_date ) ); - } + $rows[] = array( + 'id' => $maintenance->id, + 'asset_name' => $maintenance->asset->showAssetName(), + 'title' => $maintenance->title, + 'notes' => $maintenance->notes, + 'supplier' => $maintenance->supplier->name, + 'cost' => ($maintenance->cost) ? $maintenance->asset->assetloc->currency.''.$maintenance->cost : $maintenance->cost , + 'asset_maintenance_type' => e($maintenance->asset_maintenance_type), + 'start_date' => $maintenance->start_date, + 'time' => $maintenance->asset_maintenance_time, + 'completion_date' => $maintenance->completion_date, + 'actions' => $actions + ); + } - return intval( $assetMaintenances->asset_maintenance_time ); - } ) - ->addColumn( 'cost', function ( $assetMaintenances ) { + $data = array('total' => $maintenancesCount, 'rows' => $rows); - return sprintf( Lang::get( 'general.currency' ) . '%01.2f', $assetMaintenances->cost ); - } ) - ->addColumn( $actions ) - ->searchColumns( 'asset', 'supplier', 'asset_maintenance_type', 'title', 'start_date', - 'completion_date', 'asset_maintenance_time', 'cost', 'actions' ) - ->orderColumns( 'asset', 'supplier', 'asset_maintenance_type', 'title', 'start_date', - 'completion_date', 'asset_maintenance_time', 'cost', 'actions' ) - ->make(); - } + return $data; + + } /** * getCreate @@ -461,4 +453,4 @@ return View::make( 'backend/asset_maintenances/view')->with('assetMaintenance', $assetMaintenance); } - } \ No newline at end of file + } diff --git a/app/controllers/admin/AssetsController.php b/app/controllers/admin/AssetsController.php index c55c5cf1fd..87250ed1ff 100755 --- a/app/controllers/admin/AssetsController.php +++ b/app/controllers/admin/AssetsController.php @@ -26,6 +26,7 @@ use Mail; use Datatable; use TCPDF; use Slack; +use Paginator; use Manufacturer; //for embedded-create use Artisan; use Symfony\Component\Console\Output\BufferedOutput; @@ -206,7 +207,6 @@ class AssetsController extends AdminController // Redirect to the asset management page return Redirect::to('hardware')->with('error', Lang::get('admin/hardware/message.does_not_exist')); } - // Grab the dropdown lists $model_list = modelList(); $statuslabel_list = statusLabelList(); @@ -921,9 +921,23 @@ class AssetsController extends AdminController // the asset is valid if (isset($asset->id)) { - $log = Actionlog::find($fileId); - $file = $log->get_src(); - return Response::download($file); + + $log = Actionlog::find($fileId); + $file = $log->get_src(); + + $filetype = Asset::checkUploadIsImage($file); + + if ($filetype) { + + $contents = file_get_contents($file); + $response = Response::make($contents); + $response->header('Content-Type', $filetype); + return $response; + + } else { + return Response::download($file); + } + } else { // Prepare the error message $error = Lang::get('admin/hardware/message.does_not_exist', compact('id')); @@ -1083,8 +1097,29 @@ class AssetsController extends AdminController public function getDatatable($status = null) { - $assets = Asset::with('model','assigneduser','assigneduser.userloc','assetstatus','defaultLoc','assetlog','model','model.category')->Hardware()->select(array('id', 'name','model_id','assigned_to','asset_tag','serial','status_id','purchase_date','deleted_at','rtd_location_id','notes','order_number','warranty_months')); + $assets = Asset::with('model','assigneduser','assigneduser.userloc','assetstatus','defaultLoc','assetlog','model','model.category','assetstatus','assetloc') + ->Hardware(); + + if (Input::has('search')) { + $assets = $assets->TextSearch(Input::get('search')); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + if (Input::has('order_number')) { + $assets->where('order_number','=',e(Input::get('order_number'))); + } switch ($status) { case 'Deleted': @@ -1111,127 +1146,71 @@ class AssetsController extends AdminController } - if (Input::has('order_number')) { - $assets->where('order_number','=',e(Input::get('order_number'))); + $allowed_columns = ['id','name','asset_tag','serial','model','checkout_date','category','notes']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'asset_tag'; + + switch ($sort) + { + case 'model': + $assets = $assets->OrderModels($order); + break; + case 'checkout_date': + $assets = $assets->OrderCheckout($order)->first(); + break; + case 'category': + $assets = $assets->OrderCategory($order); + break; + default: + $assets = $assets->orderBy($sort, $order); + break; + } + + $assetCount = $assets->count(); + $assets = $assets->skip($offset)->take($limit)->get(); + + + $rows = array(); + foreach ($assets as $asset) { + $inout = ''; + $actions = ''; + if ($asset->deleted_at=='') { + $actions = '
'; + } elseif ($asset->model->deleted_at=='') { + $actions = ''; + } + + if ($asset->assetstatus) { + if ($asset->assetstatus->deployable != 0) { + if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) { + $inout = ''.Lang::get('general.checkin').''; + } else { + $inout = ''.Lang::get('general.checkout').''; + } + } + } + + $rows[] = array( + 'checkbox' =>'
', + 'id' => $asset->id, + 'name' => ''.$asset->name.'', + 'asset_tag' => ''.$asset->asset_tag.'', + 'serial' => $asset->serial, + 'model' => ($asset->model) ? $asset->model->name : 'No model', + 'status' => ($asset->assigneduser) ? link_to('../admin/users/'.$asset->assigned_to.'/view', $asset->assigneduser->fullName()) : (($asset->assetstatus) ? $asset->assetstatus->name : ''), + 'location' => (($asset->assigneduser) && ($asset->assigneduser->userloc!='')) ? link_to('admin/settings/locations/'.$asset->assigneduser->userloc->id.'/edit', $asset->assigneduser->userloc->name) : (($asset->defaultLoc!='') ? link_to('admin/settings/locations/'.$asset->defaultLoc->id.'/edit', $asset->defaultLoc->name) : ''), + 'category' => ($asset->model->category) ? $asset->model->category->name : 'No category', + 'eol' => ($asset->eol_date()) ? $asset->eol_date() : '', + 'notes' => $asset->notes, + 'order_number' => ($asset->order_number!='') ? ''.$asset->order_number.'' : 'none', + 'checkout_date' => (($asset->assigned_to!='')&&($asset->assetlog->first())) ? $asset->assetlog->first()->created_at->format('Y-m-d') : '', + 'change' => ($inout) ? $inout : '', + 'actions' => ($actions) ? $actions : '' + ); } - $assets = $assets->orderBy('asset_tag', 'ASC')->get(); + $data = array('total'=>$assetCount, 'rows'=>$rows); - - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function ($assets) - { - if ($assets->deleted_at=='') { - return '
'; - } elseif ($assets->deleted_at!='') { - return ''; - } - - }); - - $inout = new \Chumper\Datatable\Columns\FunctionColumn('inout', function ($assets) - { - - if ($assets->assetstatus) { - - if ($assets->assetstatus->deployable != 0) { - if (($assets->assigned_to !='') && ($assets->assigned_to > 0)) { - return ''.Lang::get('general.checkin').''; - } else { - return ''.Lang::get('general.checkout').''; - } - } - } - }); - - - - return Datatable::collection($assets) - ->addColumn('',function($assets) - { - return '
'; - }) - ->addColumn('name',function($assets) - { - return ''.$assets->name.''; - }) - ->addColumn('asset_tag',function($assets) - { - return ''.$assets->asset_tag.''; - }) - - ->showColumns('serial') - - ->addColumn('model',function($assets) - { - if ($assets->model) { - return $assets->model->name; - } else { - return 'No model'; - } - }) - - ->addColumn('status',function($assets) - { - if ($assets->assigned_to!='') { - return link_to(Config::get('app.url').'/admin/users/'.$assets->assigned_to.'/view', $assets->assigneduser->fullName()); - } else { - if ($assets->assetstatus) { - return $assets->assetstatus->name; - } - - } - - }) - ->addColumn('location',function($assets) - { - if ($assets->assigned_to && ($assets->assigneduser->userloc!='')) { - return link_to('admin/settings/locations/'.$assets->assigneduser->userloc->id.'/edit', $assets->assigneduser->userloc->name); - } elseif ($assets->defaultLoc){ - return link_to('admin/settings/locations/'.$assets->defaultLoc->id.'/edit', $assets->defaultLoc->name); - } - }) - ->addColumn('category',function($assets) - { - if (isset($assets->model->category)) { - return $assets->model->category->name; - } else { - return 'No category'; - } - - }) - - ->addColumn('eol',function($assets) - { - return $assets->eol_date(); - }) - - ->addColumn('notes',function($assets) - { - return $assets->notes; - }) - ->addColumn('mac_address',function($assets) - { - return $assets->mac_address; - }) - - ->addColumn('order_number',function($assets) - { - return ''.$assets->order_number.''; - }) - - - ->addColumn('checkout_date',function($assets) - { - if (($assets->assigned_to!='') && ($assets->assetlog->first())) { - return $assets->assetlog->first()->created_at->format('Y-m-d'); - } - - }) - ->addColumn($inout) - ->addColumn($actions) - ->searchColumns('name', 'asset_tag', 'serial', 'model', 'status','location','eol','checkout_date', 'inout','category','notes','order_number','mac_address') - ->orderColumns('name', 'asset_tag', 'serial', 'model', 'status','location','eol','notes','order_number','checkout_date', 'inout','mac_address') - ->make(); - - } + return $data; + } } diff --git a/app/controllers/admin/CategoriesController.php b/app/controllers/admin/CategoriesController.php index 66e948b70b..ded6aa1e88 100755 --- a/app/controllers/admin/CategoriesController.php +++ b/app/controllers/admin/CategoriesController.php @@ -218,30 +218,58 @@ class CategoriesController extends AdminController public function getDatatable() { // Grab all the categories - $categories = Category::orderBy('created_at', 'DESC')->get(); + $categories = Category::with('assets', 'accessories'); + + if (Input::has('search')) { + $categories = $categories->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function($categories) { return ''; }); - return Datatable::collection($categories) - ->showColumns('name') - ->addColumn('category_type', function($categories) { - return ucwords($categories->category_type); - }) - ->addColumn('count', function($categories) { - return ($categories->category_type=='asset') ? link_to('/admin/settings/categories/'.$categories->id.'/view', $categories->assetscount()) : $categories->accessoriescount(); - }) - ->addColumn('acceptance', function($categories) { - return ($categories->require_acceptance=='1') ? '' : ''; - }) - ->addColumn('eula', function($categories) { - return ($categories->getEula()) ? '' : ''; - }) - ->addColumn($actions) - ->searchColumns('name','category_type','count','acceptance','eula','actions') - ->orderColumns('name','category_type','count','acceptance','eula','actions') - ->make(); + $allowed_columns = ['id','name','category_type']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $categories = $categories->orderBy($sort, $order); + + $catCount = $categories->count(); + $categories = $categories->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach ($categories as $category) { + $actions = ''; + + $rows[] = array( + 'id' => $category->id, + 'name' => $category->name, + 'category_type' => ucwords($category->category_type), + 'count' => ($category->category_type=='asset') ? link_to('/admin/settings/categories/'.$category->id.'/view', $category->assetscount()) : $category->accessoriescount(), + 'acceptance' => ($category->require_acceptance=='1') ? '' : '', + //EULA is still not working correctly + 'eula' => ($category->getEula()) ? '' : '', + 'actions' => $actions + ); + } + + $data = array('total' => $catCount, 'rows' => $rows); + + return $data; } public function getDataView($categoryID) { diff --git a/app/controllers/admin/ConsumablesController.php b/app/controllers/admin/ConsumablesController.php index fa13df47e1..173cbfd173 100644 --- a/app/controllers/admin/ConsumablesController.php +++ b/app/controllers/admin/ConsumablesController.php @@ -66,10 +66,24 @@ class ConsumablesController extends AdminController else{ // Update the consumable data - $consumable->name = e(Input::get('name')); - $consumable->category_id = e(Input::get('category_id')); - $consumable->qty = e(Input::get('qty')); - $consumable->user_id = Sentry::getId(); + $consumable->name = e(Input::get('name')); + $consumable->category_id = e(Input::get('category_id')); + $consumable->order_number = e(Input::get('order_number')); + + if (e(Input::get('purchase_date')) == '') { + $consumable->purchase_date = NULL; + } else { + $consumable->purchase_date = e(Input::get('purchase_date')); + } + + if (e(Input::get('purchase_cost')) == '0.00') { + $consumable->purchase_cost = NULL; + } else { + $consumable->purchase_cost = ParseFloat(e(Input::get('purchase_cost'))); + } + + $consumable->qty = e(Input::get('qty')); + $consumable->user_id = Sentry::getId(); // Was the consumable created? if($consumable->save()) { @@ -134,9 +148,23 @@ class ConsumablesController extends AdminController else { // Update the consumable data - $consumable->name = e(Input::get('name')); - $consumable->category_id = e(Input::get('category_id')); - $consumable->qty = e(Input::get('qty')); + $consumable->name = e(Input::get('name')); + $consumable->category_id = e(Input::get('category_id')); + $consumable->order_number = e(Input::get('order_number')); + + if (e(Input::get('purchase_date')) == '') { + $consumable->purchase_date = NULL; + } else { + $consumable->purchase_date = e(Input::get('purchase_date')); + } + + if (e(Input::get('purchase_cost')) == '0.00') { + $consumable->purchase_cost = NULL; + } else { + $consumable->purchase_cost = ParseFloat(e(Input::get('purchase_cost'))); + } + + $consumable->qty = e(Input::get('qty')); // Was the consumable created? if($consumable->save()) { @@ -338,47 +366,70 @@ class ConsumablesController extends AdminController public function getDatatable() { $consumables = Consumable::select(array('id','name','qty')) - ->whereNull('deleted_at') - ->orderBy('created_at', 'DESC'); + ->whereNull('deleted_at'); - $consumables = $consumables->get(); + if (Input::has('search')) { + $consumables = $consumables->TextSearch(Input::get('search')); + } - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions',function($consumables) - { - return 'numRemaining() > 0 ) ? '' : ' disabled').'>'.Lang::get('general.checkout').''; - }); + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $consumables->orderBy($sort, $order); + + $consumCount = $consumables->count(); + $consumables = $consumables->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($consumables as $consumable) { + $actions = 'numRemaining() > 0 ) ? '' : ' disabled').'>'.Lang::get('general.checkout').''; + + $rows[] = array( + 'id' => $consumable->id, + 'name' => link_to('admin/consumables/'.$consumable->id.'/view', $consumable->name), + 'qty' => $consumable->qty, + 'numRemaining' => $consumable->numRemaining(), + 'actions' => $actions + ); + } + + $data = array('total' => $consumCount, 'rows' => $rows); + + return $data; - return Datatable::collection($consumables) - ->addColumn('name',function($consumables) - { - return link_to('admin/consumables/'.$consumables->id.'/view', $consumables->name); - }) - ->addColumn('qty',function($consumables) - { - return $consumables->qty; - }) - ->addColumn('numRemaining',function($consumables) - { - return $consumables->numRemaining(); - }) - ->addColumn($actions) - ->searchColumns('name','qty','numRemaining','actions') - ->orderColumns('name','qty','numRemaining','actions') - ->make(); } public function getDataView($consumableID) { $consumable = Consumable::find($consumableID); $consumable_users = $consumable->users; + $count = $consumable_users->count(); + $rows = array(); - return Datatable::collection($consumable_users) - ->addColumn('name',function($consumable_users) - { - return link_to('/admin/users/'.$consumable_users->id.'/view', $consumable_users->fullName()); - }) - ->make(); + foreach ($consumable_users as $user) { + $rows[] = array( + 'name' => link_to('/admin/users/'.$user->id.'/view', $user->fullName()) + ); + } + + $data = array('total' => $count, 'rows' => $rows); + + return $data; } } diff --git a/app/controllers/admin/DepreciationsController.php b/app/controllers/admin/DepreciationsController.php index d45b3ff67f..5161829b36 100755 --- a/app/controllers/admin/DepreciationsController.php +++ b/app/controllers/admin/DepreciationsController.php @@ -22,9 +22,6 @@ class DepreciationsController extends AdminController public function getIndex() { - // Grab all the depreciations - $depreciations = Depreciation::orderBy('created_at', 'DESC')->get(); - // Show the page return View::make('backend/depreciations/index', compact('depreciations')); } @@ -123,7 +120,7 @@ class DepreciationsController extends AdminController if ($validator->fails()) { - // The given data did not pass validation + // The given data did not pass validation return Redirect::back()->withInput()->withErrors($validator->messages()); } // attempt validation @@ -137,7 +134,7 @@ class DepreciationsController extends AdminController // Redirect to the depreciation page return Redirect::to("admin/settings/depreciations/")->with('success', Lang::get('admin/depreciations/message.update.success')); } - } + } // Redirect to the depreciation management page return Redirect::to("admin/settings/depreciations/$depreciationId/edit")->with('error', Lang::get('admin/depreciations/message.update.error')); @@ -174,5 +171,55 @@ class DepreciationsController extends AdminController } + public function getDatatable() + { + $depreciations = Depreciation::select(array('id','name','months')); + + if (Input::has('search')) { + $depreciations = $depreciations->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name','months']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $depreciations->orderBy($sort, $order); + + $depreciationsCount = $depreciations->count(); + $depreciations = $depreciations->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($depreciations as $depreciation) { + $actions = ''; + + $rows[] = array( + 'id' => $depreciation->id, + 'name' => $depreciation->name, + 'months' => $depreciation->months, + 'actions' => $actions + ); + } + + $data = array('total' => $depreciationsCount, 'rows' => $rows); + + return $data; + + } + + + } diff --git a/app/controllers/admin/LicensesController.php b/app/controllers/admin/LicensesController.php index 2404412aa0..fe7743b1af 100755 --- a/app/controllers/admin/LicensesController.php +++ b/app/controllers/admin/LicensesController.php @@ -887,41 +887,40 @@ class LicensesController extends AdminController } public function getDatatable() { - $licenses = License::orderBy('created_at', 'DESC')->get(); + $licenses = License::select('id','name','serial','purchase_date','seats'); - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function($licenses) { - return 'remaincount() > 0) ? '' : 'disabled').'>'.Lang::get('general.checkout').' '; - }); + if (Input::has('search')) { + $licenses = $licenses->TextSearch(Input::get('search')); + } - return Datatable::collection($licenses) - ->addColumn('name', function($licenses) { - return link_to('/admin/licenses/'.$licenses->id.'/view', $licenses->name); - }) - ->addColumn('serial', function($licenses) { - return link_to('/admin/licenses/'.$licenses->id.'/view', mb_strimwidth($licenses->serial, 0, 50, "...")); - }) - ->addColumn('license_name', function($licenses) { - return $licenses->license_name; - }) - ->addColumn('license_email', function($licenses) { - return $licenses->license_email; - }) - ->addColumn('totalSeats', function($licenses) { - return $licenses->totalSeatsByLicenseID(); - }) - ->addColumn('remaining', function($licenses) { - return $licenses->remaincount(); - }) - ->addColumn('purchase_date', function($licenses) { - return $licenses->purchase_date; - }) - ->addColumn('notes', function($licenses) { - return $licenses->notes; - }) - ->addColumn($actions) - ->searchColumns('name','serial','totalSeats','remaining','purchase_date','actions','notes','license_name','license_email') - ->orderColumns('name','serial','totalSeats','remaining','purchase_date','actions','notes','license_name','license_email') - ->make(); + $allowed_columns = ['id','name']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $licenses = $licenses->orderBy($sort, $order); + + $licenseCount = $licenses->count(); + $licenses = $licenses->skip(Input::get('offset'))->take(Input::get('limit'))->get(); + + $rows = array(); + + foreach ($licenses as $license) { + $actions = 'remaincount() > 0) ? '' : 'disabled').'>'.Lang::get('general.checkout').' '; + + $rows[] = array( + 'id' => $license->id, + 'name' => link_to('/admin/licenses/'.$license->id.'/view', $license->name), + 'serial' => link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")), + 'totalSeats' => $license->totalSeatsByLicenseID(), + 'remaining' => $license->remaincount(), + 'purchase_date' => ($license->purchase_date) ? $license->purchase_date : '', + 'actions' => $actions + ); + } + + $data = array('total' => $licenseCount, 'rows' => $rows); + + return $data; } public function getFreeLicense($licenseId) { diff --git a/app/controllers/admin/LocationsController.php b/app/controllers/admin/LocationsController.php index 0b3c0b4aac..e1d27421bd 100755 --- a/app/controllers/admin/LocationsController.php +++ b/app/controllers/admin/LocationsController.php @@ -254,6 +254,61 @@ class LocationsController extends AdminController } + public function getDatatable() + { + $locations = Location::select(array('id','name','address','address2','city','state','zip','country','parent_id','currency'))->with('assets') + ->whereNull('deleted_at'); + + if (Input::has('search')) { + $locations = $locations->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name','address','city','state','country','currency']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $locations->orderBy($sort, $order); + + $locationsCount = $locations->count(); + $locations = $locations->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($locations as $location) { + $actions = ''; + + $rows[] = array( + 'id' => $location->id, + 'name' => link_to('admin/locations/'.$location->id.'/view', $location->name), + 'parent' => ($location->parent) ? $location->parent->name : '', + 'assets' => ($location->assets->count() + $location->assignedassets->count()), + 'address' => ($location->address) ? $location->address: '', + 'city' => $location->city, + 'state' => $location->state, + 'country' => $location->country, + 'currency' => $location->currency, + 'actions' => $actions + ); + } + + $data = array('total' => $locationsCount, 'rows' => $rows); + + return $data; + + } + } diff --git a/app/controllers/admin/ManufacturersController.php b/app/controllers/admin/ManufacturersController.php index 8551e19b2b..0b4c8a34c6 100755 --- a/app/controllers/admin/ManufacturersController.php +++ b/app/controllers/admin/ManufacturersController.php @@ -20,9 +20,6 @@ class ManufacturersController extends AdminController */ public function getIndex() { - // Grab all the manufacturers - $manufacturers = Manufacturer::orderBy('created_at', 'DESC')->get(); - // Show the page return View::make('backend/manufacturers/index', compact('manufacturers')); } @@ -192,7 +189,54 @@ class ManufacturersController extends AdminController } + public function getDatatable() + { + $manufacturers = Manufacturer::select(array('id','name'))->with('assets') + ->whereNull('deleted_at'); + if (Input::has('search')) { + $manufacturers = $manufacturers->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $manufacturers->orderBy($sort, $order); + + $manufacturersCount = $manufacturers->count(); + $manufacturers = $manufacturers->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($manufacturers as $manufacturer) { + $actions = ''; + + $rows[] = array( + 'id' => $manufacturer->id, + 'name' => link_to('admin/manufacturers/'.$manufacturer->id.'/view', $manufacturer->name), + 'assets' => $manufacturer->assetscount(), + 'actions' => $actions + ); + } + + $data = array('total' => $manufacturersCount, 'rows' => $rows); + + return $data; + + } } diff --git a/app/controllers/admin/ModelsController.php b/app/controllers/admin/ModelsController.php index 3b7a96e6e3..12ca870ec2 100755 --- a/app/controllers/admin/ModelsController.php +++ b/app/controllers/admin/ModelsController.php @@ -369,40 +369,57 @@ class ModelsController extends AdminController { $models = Model::orderBy('created_at', 'DESC')->with('category','assets','depreciation'); ($status != 'Deleted') ?: $models->withTrashed()->Deleted();; - $models = $models->get(); - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function($models) { - if($models->deleted_at=='') { - return ''; + if (Input::has('search')) { + $models = $models->TextSearch(Input::get('search')); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + + $allowed_columns = ['name']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $models = $models->orderBy($sort, $order); + + $modelCount = $models->count(); + $models = $models->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach ($models as $model) { + if ($model->deleted_at == '') { + $actions = ''; } else { - return ''; + $actions = ''; } - }); - return Datatable::collection($models) - ->addColumn('manufacturer', function($models) { - return $models->manufacturer->name; - }) - ->addColumn('name', function ($models) { - return link_to('/hardware/models/'.$models->id.'/view', $models->name); - }) - ->showColumns('modelno') - ->addColumn('asset_count', function($models) { - return $models->assets->count(); - }) - ->addColumn('depreciation', function($models) { - return (($models->depreciation)&&($models->depreciation->id > 0)) ? $models->depreciation->name.' ('.$models->depreciation->months.')' : Lang::get('general.no_depreciation'); - }) - ->addColumn('category', function($models) { - return ($models->category) ? $models->category->name : ''; - }) - ->addColumn('eol', function($models) { - return ($models->eol) ? $models->eol.' '.Lang::get('general.months') : ''; - }) - ->addColumn($actions) - ->searchColumns('name','modelno','asset_count','depreciation','category','eol','actions') - ->orderColumns('name','modelno','asset_count','depreciation','category','eol','actions') - ->make(); + $rows[] = array( + 'manufacturer' => $model->manufacturer->name, + 'name' => link_to('/hardware/models/'.$model->id.'/view', $model->name), + 'modelnumber' => $model->modelno, + 'numassets' => $model->assets->count(), + 'depreciation' => (($model->depreciation)&&($model->depreciation->id > 0)) ? $model->depreciation->name.' ('.$model->depreciation->months.')' : Lang::get('general.no_depreciation'), + 'category' => ($model->category) ? $model->category->name : '', + 'eol' => ($model->eol) ? $model->eol.' '.Lang::get('general.months') : '', + 'actions' => $actions + ); + } + + $data = array('total' => $modelCount, 'rows' => $rows); + + return $data; } @@ -411,33 +428,29 @@ class ModelsController extends AdminController $model = Model::withTrashed()->find($modelID); $modelassets = $model->assets; - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function ($modelassets) - { - if (($modelassets->assigned_to !='') && ($modelassets->assigned_to > 0)) { - return ''.Lang::get('general.checkin').''; - } else { - return ''.Lang::get('general.checkout').''; - } - }); + $modelassetsCount = $modelassets->Count(); - return Datatable::collection($modelassets) - ->addColumn('name', function ($modelassets) { - return link_to('/hardware/'.$modelassets->id.'/view', $modelassets->showAssetName()); - // return $modelassets->name; - }) - ->addColumn('asset_tag', function ($modelassets) { - return link_to('/hardware/'.$modelassets->id.'/view', $modelassets->asset_tag); - }) - ->showColumns('serial') - ->addColumn('assigned_to', function ($modelassets) { - if ($modelassets->assigned_to) { - return link_to('/admin/users/'.$modelassets->assigned_to.'/view', $modelassets->assigneduser->fullName()); + $rows = array(); + + foreach ($modelassets as $asset) { + if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) { + $actions = ''.Lang::get('general.checkin').''; + } else { + $actions = ''.Lang::get('general.checkout').''; } - }) - ->addColumn($actions) - ->searchColumns('name','asset_tag','serial','assigned_to','actions') - ->orderColumns('name','asset_tag','serial','assigned_to','actions') - ->make(); + + $rows[] = array( + 'name' => link_to('/hardware/'.$asset->id.'/view', $asset->showAssetName()), + 'asset_tag' => link_to('hardware/'.$asset->id.'/view', $asset->asset_tag), + 'serial' => $asset->serial, + 'assigned_to' => ($asset->assigned_to) ? link_to('/admin/users/'.$asset->assigned_to.'/view', $asset->assigneduser->fullName()) : '', + 'actions' => $actions + ); + } + + $data = array('total' => $modelassetsCount, 'rows' => $rows); + + return $data; } } diff --git a/app/controllers/admin/ReportsController.php b/app/controllers/admin/ReportsController.php index bab54d29f1..ce6ed1fa38 100644 --- a/app/controllers/admin/ReportsController.php +++ b/app/controllers/admin/ReportsController.php @@ -405,7 +405,7 @@ class ReportsController extends AdminController if (e( Input::get( 'purchase_date' ) ) == '1') { $header[] = 'Purchase Date'; } - if (( e( Input::get( 'purchase_cost' ) ) == '1' ) && ( e( Input::get( 'depreciation' ) ) == '0' )) { + if (( e( Input::get( 'purchase_cost' ) ) == '1' ) && ( e( Input::get( 'depreciation' ) ) != '1' )) { $header[] = 'Purchase Cost'; } if (e( Input::get( 'order' ) ) == '1') { @@ -461,7 +461,7 @@ class ReportsController extends AdminController if (e( Input::get( 'purchase_date' ) ) == '1') { $row[] = $asset->purchase_date; } - if (e( Input::get( 'purchase_cost' ) ) == '1') { + if (e( Input::get( 'purchase_cost' ) ) == '1' && ( e( Input::get( 'depreciation' ) ) != '1' )) { $row[] = '"' . number_format( $asset->purchase_cost ) . '"'; } if (e( Input::get( 'order' ) ) == '1') { diff --git a/app/controllers/admin/SettingsController.php b/app/controllers/admin/SettingsController.php index c714fefac1..e4a572298d 100755 --- a/app/controllers/admin/SettingsController.php +++ b/app/controllers/admin/SettingsController.php @@ -68,7 +68,8 @@ class SettingsController extends AdminController // Declare the rules for the form validation $rules = array( - "per_page" => 'required|min:1|numeric', + "brand" => 'required|min:1|numeric', + "per_page" => 'required|min:1|numeric', "qr_text" => 'min:1|max:31', "logo" => 'mimes:jpeg,bmp,png,gif', "custom_css" => 'alpha_space', @@ -115,6 +116,7 @@ class SettingsController extends AdminController if (Config::get('app.lock_passwords')==false) { $setting->site_name = e(Input::get('site_name')); + $setting->brand = e(Input::get('brand')); $setting->custom_css = e(Input::get('custom_css')); } diff --git a/app/controllers/admin/StatuslabelsController.php b/app/controllers/admin/StatuslabelsController.php index ced912ca5f..1266a8dfb0 100755 --- a/app/controllers/admin/StatuslabelsController.php +++ b/app/controllers/admin/StatuslabelsController.php @@ -24,9 +24,6 @@ class StatuslabelsController extends AdminController public function getIndex() { - // Grab all the statuslabels - $statuslabels = Statuslabel::orderBy('created_at', 'DESC')->get(); - // Show the page return View::make('backend/statuslabels/index', compact('statuslabels')); } @@ -230,5 +227,67 @@ class StatuslabelsController extends AdminController } + public function getDatatable() + { + $statuslabels = Statuslabel::select(array('id','name','deployable','pending','archived')) + ->whereNull('deleted_at'); + + if (Input::has('search')) { + $statuslabels = $statuslabels->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $statuslabels->orderBy($sort, $order); + + $statuslabelsCount = $statuslabels->count(); + $statuslabels = $statuslabels->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($statuslabels as $statuslabel) { + + if ($statuslabel->deployable == 1) { + $label_type = Lang::get('admin/statuslabels/table.deployable'); + } elseif ($statuslabel->pending == 1) { + $label_type = Lang::get('admin/statuslabels/table.pending'); + } elseif ($statuslabel->archived == 1) { + $label_type = Lang::get('admin/statuslabels/table.archived'); + } else { + $label_type = Lang::get('admin/statuslabels/table.undeployable'); + } + + $actions = ''; + + $rows[] = array( + 'id' => $statuslabel->id, + 'type' => $label_type, + 'name' => e($statuslabel->name), + 'actions' => $actions + ); + } + + $data = array('total' => $statuslabelsCount, 'rows' => $rows); + + return $data; + + } + + + } diff --git a/app/controllers/admin/SuppliersController.php b/app/controllers/admin/SuppliersController.php index 2244459285..1b078bbd59 100755 --- a/app/controllers/admin/SuppliersController.php +++ b/app/controllers/admin/SuppliersController.php @@ -103,7 +103,7 @@ class SuppliersController extends AdminController return Redirect::to('admin/settings/suppliers/create')->with('error', Lang::get('admin/suppliers/message.create.error')); } - + public function store() { $supplier=new Supplier; @@ -115,7 +115,7 @@ class SuppliersController extends AdminController //$supplier->fill($new); $supplier->name=$new['name']; $supplier->user_id = Sentry::getId(); - + if($supplier->save()) { return JsonResponse::create($supplier); } else { @@ -163,7 +163,7 @@ class SuppliersController extends AdminController if ($validator->fails()) { - // The given data did not pass validation + // The given data did not pass validation return Redirect::back()->withInput()->withErrors($validator->messages()); } // attempt validation @@ -204,7 +204,7 @@ class SuppliersController extends AdminController // Redirect to the new supplier page return Redirect::to("admin/settings/suppliers")->with('success', Lang::get('admin/suppliers/message.update.success')); } - } + } // Redirect to the supplier management page return Redirect::to("admin/settings/suppliers/$supplierId/edit")->with('error', Lang::get('admin/suppliers/message.update.error')); @@ -264,6 +264,61 @@ class SuppliersController extends AdminController } + public function getDatatable() + { + $suppliers = Supplier::select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact')) + ->whereNull('deleted_at'); + + if (Input::has('search')) { + $suppliers = $suppliers->TextSearch(e(Input::get('search'))); + } + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + $allowed_columns = ['id','name','address','phone','contact','fax','email']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at'; + + $suppliers->orderBy($sort, $order); + + $suppliersCount = $suppliers->count(); + $suppliers = $suppliers->skip($offset)->take($limit)->get(); + + $rows = array(); + + foreach($suppliers as $supplier) { + $actions = ''; + + $rows[] = array( + 'id' => $supplier->id, + 'name' => link_to('admin/settings/suppliers/'.$supplier->id.'/view', $supplier->name), + 'contact' => $supplier->contact, + 'address' => $supplier->address.' '.$supplier->address2.' '.$supplier->city.' '.$supplier->state.' '.$supplier->country, + 'phone' => $supplier->phone, + 'fax' => $supplier->fax, + 'email' => ($supplier->email!='') ? ''.$supplier->email.'' : '', + 'assets' => $supplier->num_assets(), + 'licenses' => $supplier->num_licenses(), + 'actions' => $actions + ); + } + + $data = array('total' => $suppliersCount, 'rows' => $rows); + + return $data; + + } + } diff --git a/app/controllers/admin/UsersController.php b/app/controllers/admin/UsersController.php index cc40728bbb..a509cf35f1 100755 --- a/app/controllers/admin/UsersController.php +++ b/app/controllers/admin/UsersController.php @@ -824,94 +824,105 @@ class UsersController extends AdminController { return Redirect::route('users')->with('duplicates', $duplicates)->with('success', 'Success'); } - public function getDatatable($status = null) { + public function getDatatable($status = null) + { + + if (Input::has('offset')) { + $offset = e(Input::get('offset')); + } else { + $offset = 0; + } + + if (Input::has('limit')) { + $limit = e(Input::get('limit')); + } else { + $limit = 50; + } + + if (Input::get('sort')=='name') { + $sort = 'first_name'; + } else { + $sort = e(Input::get('sort')); + } $users = User::with('assets', 'accessories', 'consumables', 'licenses', 'manager', 'sentryThrottle', 'groups', 'userloc'); switch ($status) { - case 'deleted': - $users->GetDeleted(); - break; - case '': - $users->GetNotDeleted(); - break; + case 'deleted': + $users = $users->withTrashed()->Deleted(); + break; } - $users = $users->orderBy('created_at', 'DESC')->get(); - - $actions = new \Chumper\Datatable\Columns\FunctionColumn('actions', function ($users) { - $action_buttons = ''; - if (!is_null($users->deleted_at)) { - $action_buttons .= ' '; + if (Input::has('search')) { + $users = $users->TextSearch(Input::get('search')); + } + + $allowed_columns = ['last_name','first_name','email','username','manager','location','assets','accessories', 'consumables','licenses','groups']; + $order = Input::get('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array($sort, $allowed_columns) ? $sort : 'first_name'; + + + $userCount = $users->count(); + $users = $users->skip($offset)->take($limit)->orderBy($sort, $order)->get(); + + + $rows = array(); + + foreach ($users as $user) + { + + $group_names = ''; + $inout = ''; + $actions = ''; + + foreach ($user->groups as $group) { + $group_names .= '' . $group->name . ' '; + } + + + if (!is_null($user->deleted_at)) { + + $actions .= ' '; } else { - if ($users->accountStatus() == 'suspended') { - $action_buttons .= ' '; + + if ($user->accountStatus() == 'suspended') { + $actions .= ' '; } - $action_buttons .= ' '; + $actions .= ' '; - if ((Sentry::getId() !== $users->id) && (!Config::get('app.lock_passwords'))) { - $action_buttons .= ' '; + if ((Sentry::getId() !== $user->id) && (!Config::get('app.lock_passwords'))) { + $actions .= ' '; } else { - $action_buttons .= ' '; + $actions .= ' '; } } - return $action_buttons; - }); + $actions .= ''; + $rows[] = array( + 'checkbox' =>'', + 'name' => ''.$user->fullName().'', + 'email' => ($user->email!='') ? + '' + .'' + .'' : '', + 'username' => $user->username, + 'location' => ($user->userloc) ? $user->userloc->name : '', + 'manager' => ($user->manager) ? '' . $user->manager->fullName() . '' : '', + 'assets' => $user->assets->count(), + 'licenses' => $user->licenses->count(), + 'accessories' => $user->accessories->count(), + 'consumables' => $user->consumables->count(), + 'groups' => $group_names, + 'notes' => $user->notes, + 'actions' => ($actions) ? $actions : '' + ); + } - return Datatable::collection($users) - ->addColumn('', function($users) { - return '
'; - }) - ->addColumn('name', function($users) { - return '' . $users->fullName() . ''; - }) - ->addColumn('email', function($users) { - if ($users->email) { - return '
'; - } else { - return ''; - } - }) - ->addColumn('username', function($users) { - return $users->username; - }) - ->addColumn('manager', function($users) { - if ($users->manager) { - return '' . $users->manager->fullName() . ''; - } - }) - ->addColumn('location', function($users) { - if ($users->userloc) { - return $users->userloc->name; - } - }) - ->addColumn('assets', function($users) { - return $users->assets->count(); - }) - ->addColumn('licenses', function($users) { - return $users->licenses->count(); - }) - ->addColumn('accessories', function($users) { - return $users->accessories->count(); - }) - ->addColumn('consumables', function($users) { - return $users->consumables->count(); - }) - ->addColumn('groups', function($users) { - $group_names = ''; - foreach ($users->groups as $group) { - $group_names .= '' . $group->name . ' '; - } - return $group_names; - }) - ->addColumn($actions) - ->searchColumns('name', 'email', 'username', 'manager', 'activated', 'groups', 'location') - ->orderColumns('name', 'email', 'username', 'manager', 'activated', 'licenses', 'assets', 'accessories', 'consumables', 'groups', 'location') - ->make(); + $data = array('total'=>$userCount, 'rows'=>$rows); + return $data; } /** diff --git a/app/database/migrations/2015_10_01_024551_add_accessory_consumable_price_info.php b/app/database/migrations/2015_10_01_024551_add_accessory_consumable_price_info.php new file mode 100644 index 0000000000..21bbefc6ac --- /dev/null +++ b/app/database/migrations/2015_10_01_024551_add_accessory_consumable_price_info.php @@ -0,0 +1,48 @@ +date('purchase_date')->nullable(); + $table->decimal('purchase_cost', 13, 4)->nullable(); + $table->string('order_number'); + }); + + Schema::table('consumables', function ($table) { + $table->date('purchase_date')->nullable(); + $table->decimal('purchase_cost', 13, 4)->nullable(); + $table->string('order_number'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('accessories', function ($table) { + $table->dropColumn('purchase_date'); + $table->dropColumn('purchase_cost'); + $table->dropColumn('order_number'); + }); + + Schema::table('consumables', function ($table) { + $table->dropColumn('purchase_date'); + $table->dropColumn('purchase_cost'); + $table->dropColumn('order_number'); + }); + } + +} diff --git a/app/database/migrations/2015_10_12_192706_add_brand_to_settings.php b/app/database/migrations/2015_10_12_192706_add_brand_to_settings.php new file mode 100644 index 0000000000..eae3acd849 --- /dev/null +++ b/app/database/migrations/2015_10_12_192706_add_brand_to_settings.php @@ -0,0 +1,34 @@ +tinyInteger('brand')->default(1); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('settings', function(Blueprint $table) + { + $table->dropColumn('brand'); + }); + } + +} diff --git a/app/database/migrations/2015_10_22_003314_fix_defaults_accessories.php b/app/database/migrations/2015_10_22_003314_fix_defaults_accessories.php new file mode 100644 index 0000000000..34059de1ee --- /dev/null +++ b/app/database/migrations/2015_10_22_003314_fix_defaults_accessories.php @@ -0,0 +1,32 @@ + 'Accessories are anything you issue to users but that do not have a serial number (or you do not care about tracking them uniquely). For example, computer mice or keyboards.', 'accessory_category' => 'Accessory Category', 'accessory_name' => 'Accessory Name', + 'cost' => 'Purchase Cost', 'create' => 'Create Accessory', + 'date' => 'Purchase Date', 'eula_text' => 'Category EULA', 'eula_text_help' => 'This field allows you to customize your EULAs for specific types of assets. If you only have one EULA for all of your assets, you can check the box below to use the primary default.', 'require_acceptance' => 'Require users to confirm acceptance of assets in this category.', 'no_default_eula' => 'No primary default EULA found. Add one in Settings.', + 'order' => 'Order Number', 'qty' => 'QTY', 'total' => 'Total', 'remaining' => 'Avail', diff --git a/app/lang/en/admin/asset_maintenances/form.php b/app/lang/en/admin/asset_maintenances/form.php index 785d06b08f..2aa005c45f 100755 --- a/app/lang/en/admin/asset_maintenances/form.php +++ b/app/lang/en/admin/asset_maintenances/form.php @@ -1,14 +1,14 @@ 'Asset Maintenance Type', + 'asset_maintenance_type' => 'Maintenance Type', 'title' => 'Title', - 'start_date' => 'Start Date', - 'completion_date' => 'Completion Date', + 'start_date' => 'Started', + 'completion_date' => 'Completed', 'cost' => 'Cost', 'is_warranty' => 'Warranty Improvement', - 'asset_maintenance_time' => 'Asset Maintenance Time (in days)', + 'asset_maintenance_time' => 'Days', 'notes' => 'Notes', - 'update' => 'Update Asset Maintenance', - 'create' => 'Create Asset Maintenance' + 'update' => 'Update', + 'create' => 'Create' ]; diff --git a/app/lang/en/admin/asset_maintenances/table.php b/app/lang/en/admin/asset_maintenances/table.php index 02e9060bf6..5b83539914 100755 --- a/app/lang/en/admin/asset_maintenances/table.php +++ b/app/lang/en/admin/asset_maintenances/table.php @@ -2,8 +2,8 @@ return [ 'title' => 'Asset Maintenance', - 'asset_name' => 'Asset Name', - 'supplier_name' => 'Supplier Name', + 'asset_name' => 'Asset', + 'supplier_name' => 'Supplier', 'is_warranty' => 'Warranty', 'dl_csv' => 'Download CSV' - ]; \ No newline at end of file + ]; diff --git a/app/lang/en/admin/consumables/general.php b/app/lang/en/admin/consumables/general.php index 01ab4eb692..b29947f13a 100755 --- a/app/lang/en/admin/consumables/general.php +++ b/app/lang/en/admin/consumables/general.php @@ -4,7 +4,10 @@ return array( 'about_consumables_title' => 'About Consumables', 'about_consumables_text' => 'Consumables are anything purchased that will be used up over time. For example, printer ink or copier paper.', 'consumable_name' => 'Consumable Name', + 'cost' => 'Purchase Cost', 'create' => 'Create Consumable', + 'date' => 'Purchase Date', + 'order' => 'Order Number', 'remaining' => 'Remaining', 'total' => 'Total', 'update' => 'Update Consumable', diff --git a/app/lang/en/admin/settings/general.php b/app/lang/en/admin/settings/general.php index ff19aca7e7..d4f404c00c 100755 --- a/app/lang/en/admin/settings/general.php +++ b/app/lang/en/admin/settings/general.php @@ -26,7 +26,8 @@ return array( 'header_color' => 'Header Color', 'info' => 'These settings let you customize certain aspects of your installation.', 'laravel' => 'Laravel Version', - 'load_remote' => 'This Snipe-IT install can load scripts from the outside world.', + 'load_remote_text' => 'Remote Scripts', + 'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.', 'logo' => 'Logo', 'optional' => 'optional', 'per_page' => 'Results Per Page', @@ -47,4 +48,7 @@ return array( 'system' => 'System Information', 'update' => 'Update Settings', 'value' => 'Value', + 'brand' => 'Branding', + 'about_settings_title' => 'About Settings', + 'about_settings_text' => 'These settings let you customize certain aspects of your installation.', ); diff --git a/app/models/Accessory.php b/app/models/Accessory.php index 5c016fe724..0abed13fcb 100755 --- a/app/models/Accessory.php +++ b/app/models/Accessory.php @@ -12,7 +12,7 @@ class Accessory extends Elegant public $rules = array( 'name' => 'required|alpha_space|min:3|max:255', 'category_id' => 'required|integer', - 'qty' => 'required|integer|min:0', + 'qty' => 'required|integer|min:1', ); public function category() @@ -68,5 +68,21 @@ class Accessory extends Elegant return $remaining; } + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Asset.php b/app/models/Asset.php index e3af7c8feb..d08e657a69 100755 --- a/app/models/Asset.php +++ b/app/models/Asset.php @@ -1,10 +1,9 @@ orderBy( 'created_at', 'desc' ); } + public static function checkUploadIsImage($file) { + // Check if the file is an image, so we can show a preview + $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension + $filetype = finfo_file($finfo, $file); + finfo_close($finfo); + + if (($filetype=="image/jpeg") || ($filetype=="image/jpg") || ($filetype=="image/gif")) { + return true; + } + + return false; + } + public function assigneduser() { @@ -381,28 +393,23 @@ $settings = Setting::getSettings(); - if ($settings->auto_increment_assets == '1') { - $asset_tag = DB::table( 'assets' ) - ->where( 'physical', '=', '1' ) - ->max( 'id' ); + if ($settings->auto_increment_assets == '1') { + $asset_tag = DB::table('assets') + ->where('physical', '=', '1') + ->max('id'); + return $settings->auto_increment_prefix.($asset_tag + 1); + } else { + return false; + } + } - return $settings->auto_increment_prefix . ( $asset_tag + 1 ); - } else { - return false; - } - } + public function checkin_email() { + return $this->model->category->checkin_email; + } - public function checkin_email() - { - - return $this->model->category->checkin_email; - } - - public function requireAcceptance() - { - - return $this->model->category->require_acceptance; - } + public function requireAcceptance() { + return $this->model->category->require_acceptance; + } public function getEula() { @@ -560,45 +567,92 @@ * @return Illuminate\Database\Query\Builder Modified query builder */ - public function scopeDeleted( $query ) - { + public function scopeDeleted($query) + { + return $query->whereNotNull('deleted_at'); + } - return $query->whereNotNull( 'deleted_at' ); - } +/** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + $search = explode('+', $search); - /** - * scopeInModelList - * Get all assets in the provided listing of model ids - * - * @param $query - * @param array $modelIdListing - * - * @return mixed - * @author Vincent Sposato - * @version v1.0 - */ - public function scopeInModelList( $query, array $modelIdListing ) - { + return $query->where(function($query) use ($search) + { + foreach ($search as $search) { + $query->whereHas('model', function($query) use ($search) { + $query->whereHas('category', function($query) use ($search) { + $query->where(function($query) use ($search) { + $query->where('categories.name','LIKE','%'.$search.'%') + ->orWhere('models.name','LIKE','%'.$search.'%'); + }); + }); + })->orWhere(function($query) use ($search) { + $query->whereHas('assetstatus', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + })->orWhere(function($query) use ($search) { + $query->whereHas('defaultLoc', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + })->orWhere(function($query) use ($search) { + $query->whereHas('assigneduser', function($query) use ($search) { + $query->where(function($query) use ($search) { + $query->where('users.first_name','LIKE','%'.$search.'%') + ->orWhere('users.last_name','LIKE','%'.$search.'%') + ->orWhere(function($query) use ($search) { + $query->whereHas('userloc', function($query) use ($search) { + $query->where('locations.name','LIKE','%'.$search.'%'); + }); + }); + }); + }); + })->orWhere(function($query) use ($search) { + $query->whereHas('assetlog', function($query) use ($search) { + $query->where('action_type','=','checkout') + ->where('created_at','LIKE','%'.$search.'%'); + }); + })->orWhere('name','LIKE','%'.$search.'%') + ->orWhere('asset_tag','LIKE','%'.$search.'%') + ->orWhere('serial','LIKE','%'.$search.'%') + ->orWhere('order_number','LIKE','%'.$search.'%') + ->orWhere('notes','LIKE','%'.$search.''); + } + }); + } - return $query->whereIn( 'model_id', $modelIdListing ); - } + /** + * Query builder scope to order on model + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $order Order + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeOrderModels($query, $order) + { + return $query->join('models', 'assets.model_id', '=', 'models.id')->orderBy('models.name', $order); + } - public function scopeNotYetAccepted( $query ) - { + public function scopeOrderCheckout($query, $order) + { + return $query->join('asset_logs', function($join){ + $join->on('assets.id', '=', 'asset_logs.asset_id'); + })->where('asset_logs.action_type', '=', 'checkout') + ->orderBy('asset_logs.created_at', $order); + } - return $query->where( "accepted", "=", "pending" ); - } - - public function scopeRejected( $query ) - { - - return $query->where( "accepted", "=", "rejected" ); - } - - public function scopeAccepted( $query ) - { - - return $query->where( "accepted", "=", "accepted" ); - } - - } + public function scopeOrderCategory($query, $order) + { + return $query->join('models', 'assets.model_id', '=', 'models.id') + ->join('categories', 'models.category_id', '=', 'categories.id') + ->orderBy('categories.name', $order); + } +} diff --git a/app/models/AssetMaintenance.php b/app/models/AssetMaintenance.php index 9d42f381ba..9a99c8d99f 100644 --- a/app/models/AssetMaintenance.php +++ b/app/models/AssetMaintenance.php @@ -81,4 +81,26 @@ return $query->whereNotNull( 'deleted_at' ); } - } \ No newline at end of file + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('title', 'LIKE', '%'.$search.'%') + ->orWhere('notes', 'LIKE', '%'.$search.'%') + ->orWhere('asset_maintenance_type', 'LIKE', '%'.$search.'%') + ->orWhere('cost', 'LIKE', '%'.$search.'%') + ->orWhere('start_date', 'LIKE', '%'.$search.'%') + ->orWhere('completion_date', 'LIKE', '%'.$search.'%'); + }); + } + } diff --git a/app/models/Category.php b/app/models/Category.php index 77a59b5c69..6df3fcee5a 100755 --- a/app/models/Category.php +++ b/app/models/Category.php @@ -74,5 +74,23 @@ class Category extends Elegant return $query->where( 'require_acceptance', '=', true ); } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%') + ->orWhere('category_type', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Consumable.php b/app/models/Consumable.php index ccb45cc5cf..dad42a771d 100644 --- a/app/models/Consumable.php +++ b/app/models/Consumable.php @@ -64,6 +64,22 @@ class Consumable extends Elegant $remaining = $total - $checkedout; return $remaining; } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Depreciation.php b/app/models/Depreciation.php index 1b1506f9d0..ac656c9716 100755 --- a/app/models/Depreciation.php +++ b/app/models/Depreciation.php @@ -17,4 +17,22 @@ class Depreciation extends Elegant { return $this->hasMany('License','depreciation_id')->count(); } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%') + ->orWhere('months', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/License.php b/app/models/License.php index 3a55253d66..08476fe646 100755 --- a/app/models/License.php +++ b/app/models/License.php @@ -176,4 +176,26 @@ public function freeSeat() ->get(); } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%') + ->orWhere('serial', 'LIKE', '%'.$search.'%') + ->orWhere('notes', 'LIKE', '%'.$search.'%') + ->orWhere('order_number', 'LIKE', '%'.$search.'%') + ->orWhere('purchase_date', 'LIKE', '%'.$search.'%') + ->orWhere('purchase_cost', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Location.php b/app/models/Location.php index 8a83eaa809..df49df8dbf 100755 --- a/app/models/Location.php +++ b/app/models/Location.php @@ -88,5 +88,33 @@ class Location extends Elegant return $location_options; } + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextsearch($query, $search) + { + + return $query->where('name', 'LIKE', "%$search%") + ->orWhere('address', 'LIKE', "%$search%") + ->orWhere('city', 'LIKE', "%$search%") + ->orWhere('state', 'LIKE', "%$search%") + ->orWhere('zip', 'LIKE', "%$search%") + + // This doesn't actually work - need to use a table alias maybe? + ->orWhere(function($query) use ($search) { + $query->whereHas('parent', function($query) use ($search) { + $query->where(function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + }); + }); + + } + } diff --git a/app/models/Manufacturer.php b/app/models/Manufacturer.php index 6051237152..1831c150f5 100755 --- a/app/models/Manufacturer.php +++ b/app/models/Manufacturer.php @@ -26,4 +26,20 @@ class Manufacturer extends Elegant return $this->hasManyThrough('Asset', 'Model'); } + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Model.php b/app/models/Model.php index 039a771473..a8d7e87266 100755 --- a/app/models/Model.php +++ b/app/models/Model.php @@ -83,4 +83,35 @@ class Model extends Elegant return $query->whereIn( 'category_id', $categoryIdListing ); } + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where('name', 'LIKE', "%$search%") + ->orWhere('modelno', 'LIKE', "%$search%") + ->orWhere(function($query) use ($search) { + $query->whereHas('depreciation', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + }) + ->orWhere(function($query) use ($search) { + $query->whereHas('category', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + }) + ->orWhere(function($query) use ($search) { + $query->whereHas('manufacturer', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + }); + + } + } diff --git a/app/models/Statuslabel.php b/app/models/Statuslabel.php index 0192e20685..aece44319a 100755 --- a/app/models/Statuslabel.php +++ b/app/models/Statuslabel.php @@ -55,4 +55,21 @@ class Statuslabel extends Elegant return $statustype; } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/Supplier.php b/app/models/Supplier.php index b2b34ad906..d5f3df938a 100755 --- a/app/models/Supplier.php +++ b/app/models/Supplier.php @@ -52,4 +52,21 @@ class Supplier extends Elegant } return $url; } + + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextSearch($query, $search) + { + + return $query->where(function($query) use ($search) + { + $query->where('name', 'LIKE', '%'.$search.'%'); + }); + } } diff --git a/app/models/User.php b/app/models/User.php index 4f51934e10..b245f87ad2 100755 --- a/app/models/User.php +++ b/app/models/User.php @@ -200,5 +200,55 @@ class User extends SentryUserModel } + /** + * Query builder scope to search on text + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * @param text $search Search term + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeTextsearch($query, $search) + { + + return $query->where(function($query) use ($search) { + $query->where('first_name', 'LIKE', "%$search%") + ->orWhere('last_name', 'LIKE', "%$search%") + ->orWhere('email', 'LIKE', "%$search%") + ->orWhere('username', 'LIKE', "%$search%") + ->orWhere('notes', 'LIKE', "%$search%") + ->orWhere(function($query) use ($search) { + $query->whereHas('userloc', function($query) use ($search) { + $query->where('name','LIKE','%'.$search.'%'); + }); + }) + + // This doesn't actually work - need to use a table alias maybe? + ->orWhere(function($query) use ($search) { + $query->whereHas('manager', function($query) use ($search) { + $query->where(function($query) use ($search) { + $query->where('first_name','LIKE','%'.$search.'%') + ->orWhere('last_name','LIKE','%'.$search.'%'); + }); + }); + }); + }); + + } + + + /** + * Query builder scope for Deleted users + * + * @param Illuminate\Database\Query\Builder $query Query builder instance + * + * @return Illuminate\Database\Query\Builder Modified query builder + */ + + public function scopeDeleted($query) + { + return $query->whereNotNull('deleted_at'); + } + } diff --git a/app/private_uploads/imports/assets/sample.csv b/app/private_uploads/imports/assets/sample.csv index 3bf49568df..ba2752659b 100644 --- a/app/private_uploads/imports/assets/sample.csv +++ b/app/private_uploads/imports/assets/sample.csv @@ -1 +1 @@ -Name,Email,Username,Asset Category,Asset Model,Manufacturer,Asset Model Number,Asset Serial,Asset Tag,Location Name,Asset Notes,Purchase Date,Purchase Cost William Dixon,miranda@selfware.ch,,Malesuada,Et,Nisi,5,4D47A5B7-007D-47F3-B1F2-28C33D3F2C54,58SG1MLI,"Tanzania, United Republic of",Accumsan condimentum sed purus ante mauris tincidunt aliquam libero tempor arcu posuere curabitur sodales imperdiet.,2/16/13,892.46 Debbie Mullins,jesper@madefeed.cf,,At,Platea,Torquent,9,6DEC0B69-32DB-4801-81FA-07C58E5386CC,FIM4P54T,Isle of Man,Sodales enim duis egestas turpis arcu justo aliquam ipsum erat in cursus iaculis taciti nullam.,4/12/10,961.03 Wolfgang Mitchell,kirk@tagbase.kp,,Id,Vel,Eu,5,D4017718-D68C-40EC-8669-52745A34B048,SY4NFU7S,Cook Islands,Ac platea nunc nibh in nibh eu arcu eu felis congue nibh aenean morbi quis scelerisque.,4/29/14,771.68 Anne-Marie Wallace,le@tidything.ac,,Morbi,Sociosqu,Nisl,5,56CC5079-F44B-4D62-BC45-1A4CA4FB8C9F,SK6VTSTG,Uruguay,Nostra ut mauris consectetuer donec scelerisque est per pellentesque nec id urna magna.,8/18/14,325.22 Shane Booker,alain@quitsource.pa,,Fusce,Fermentum,Sagittis,7,ED248E82-046B-4046-84DA-E4F4A0B55D0E,DBEUH6H2,Curaí_ao,Sed magna inceptos fames ultrices per ut eleifend tellus in class.,10/12/12,951.21 Olivier Walter,margaret@quitbot.tf,,Malesuada,Et,Nisi,6,FC741D83-3F19-4259-94EC-FFAB3C15C747,40SI9NUR,El Salvador,Orci tortor sed vestibulum nec imperdiet vivamus ridiculus feugiat neque ut pellentesque felis.,8/14/11,368.9 Adrian Montgomery,welch@busybeat.kp,,Malesuada,Et,Nisi,6,E8E3709B-377E-4FC7-B1B7-1DE0EE60798B,LUXLI88S,Bosnia and Herzegovina,Dapibus scelerisque tempor nisl nascetur dictum vulputate mi.,9/2/13,276.77 Joan Merrill,massey@jetwords.at,,Malesuada,Et,Nisi,6,3D862DC2-74B5-4744-8D8B-41A757927EB8,ENAZFLV3,Tonga,Malesuada felis accumsan gravida sagittis lacinia pede orci nulla magna litora augue orci.,8/31/14,123.23 Stella Gilmore,wright@quitsource.jp,,Malesuada,Et,Nisi,5,1E420152-929A-4363-8864-7DE01D38BDE0,8JS4P5P2,Uruguay,Magna in interdum consectetuer consequat tristique dapibus class nulla quis massa dictumst ipsum imperdiet.,4/22/12,333.44 Georgina Wiley,rivera@lowwerk.lv,,Urna,Et,Integer,10,6E668691-2560-4E3D-89D4-1CDB7404BB8F,J3KHF9EK,Georgia,Consequat non per viverra porta torquent in non et suspendisse bibendum scelerisque sapien mi elit nostra imperdiet.,12/16/14,588.07 Barry Hudson,jane@tagbot.tc,,Nam,Vivamus,Nibh,5,26825937-9579-4B57-9678-0659A2BB75D7,1V1WQAZA,Poland,Molestie tortor posuere duis lacus feugiat nibh mollis pellentesque nibh mollis tincidunt nisl ut inceptos ac pretium.,4/7/13,839.61 Leigh Stewart,jim.douglas@quitpower.si,,In,Mauris,Et,9,F5A3666A-951B-46FD-84AF-C0B36BE34243,8PU2UCVH,Uzbekistan,Praesent lectus amet fusce a aliquet pellentesque justo etiam vulputate nec.,3/17/14,724.88 Travis Flynn,nigel.blackburn@gigabase.md,,Nonummy,Mattis,Justo,7,008A88C0-355D-40F9-B601-7478901147E4,8O77P76Z,Hungary,Massa suscipit porta sapien purus quis metus quis vivamus curae; suspendisse ut imperdiet dapibus.,4/3/12,625.79 Edward Park,sanders@madeclicks.travel,,Nonummy,Mattis,Justo,9,228F09D4-F8A4-4453-BD7F-6FDB4FCFCE0A,FNKJCPIY,Uzbekistan,Neque eu non a felis enim turpis eget mauris lorem.,6/22/12,122.28 Stig Molina,lester@getdesk.at,,Nonummy,Mattis,Justo,9,BA720380-E958-4D09-8EF2-D5B6FDF0736C,C4DXBUKJ,Georgia,Mollis ut sapien in id pede gravida ante eu nisl aenean ullamcorper potenti nulla parturient nam quisque.,7/10/13,178.12 Bruce Watts,ali.hobbs@gigawerk.gu,,Nonummy,Mattis,Justo,7,2AF6BE26-EB5F-4745-8822-D54B3536EF9E,W9PO94OR,Finland,Ante facilisis ullamcorper eleifend enim quam justo vestibulum.,8/26/15,583.97 Lincoln Soto,michelle.daniel@presssource.sk,,Nonummy,Mattis,Justo,5,913AEF6D-547C-41DD-9128-2A6FEF5E5118,9DOEWENU,Benin,Sociis aptent ipsum leo sodales mattis leo sociosqu at amet ligula.,6/22/11,581.01 Camilla Morrison,charles@chatspace.th,,Ad,Elit,Ullamcorper,7,2ACA4B3C-A619-48AF-9530-8B581E5F9DBA,2AF7QYGX,Uzbekistan,Molestie quis placerat magna turpis iaculis eget nam massa sit congue erat hac habitant lacinia nibh.,2/28/15,492.81 Josie English,stafford@rollthing.nf,,Eu,Aliquam,Enim,7,34302A6E-CB8F-4691-9D9B-845887D0F5B2,Q7ALASVU,Botswana,Rhoncus hymenaeos sed torquent vestibulum nec mauris id nulla nibh purus purus donec vel nibh morbi.,7/15/13,441.14 Alia Salazar,johan.cook@pressbit.ai,,Ipsum,Velit,Magna,9,E429BE64-8E1B-4C8F-BB31-C4B2F2754C3C,HKZ2HG9E,New Caledonia,Sed praesent sed rutrum massa suscipit magna mauris interdum massa.,3/28/13,384.99 Beth Sweeney,coral.le@chatsource.dj,,Ipsum,Velit,Magna,8,3FC9CF5F-EBCC-4482-8F0D-7F99EE2911A4,UM5HO5SD,Vanuatu,Aliquet porttitor elit sagittis mauris nibh rutrum tristique nunc erat mauris per integer nostra imperdiet.,9/2/15,575.23 Stig Bender,lydia@rollsimple.tp,,Ipsum,Velit,Magna,9,A39EB068-99C6-4377-AB3F-CACC83E083D1,NHYLZ75J,Burundi,Lobortis morbi massa praesent eu ac ad ut nunc aliquam neque scelerisque est fermentum eget elit aenean.,11/29/09,277.87 Angelique Lindsay,villarreal@selfserv.sg,,Ipsum,Velit,Magna,6,EA864247-21AF-44C9-96CC-D6900C599740,PZ9MMXYD,Lithuania,Id eu molestie adipiscing phasellus duis imperdiet aliquam conubia ligula eget morbi.,8/14/14,552.75 Guillermo Black,raimonds@gigadesk.bd,,Id,Class,Laoreet,5,543C547F-91CD-4AFD-AFBF-2E2B68FD514D,M3VRKBBJ,Equatorial Guinea,Egestas pretium sollicitudin suspendisse erat sem massa adipiscing eu tempor libero sollicitudin a curabitur mauris.,1/1/14,582.02 Christof Castaneda,campos@fuelserv.bg,,Eget,Congue,Nisi,6,CAB3E433-8409-475C-8EA0-2801C22B2C2B,B0CGYUG7,Syrian Arab Republic,Feugiat facilisis consequat sociosqu ac consequat lacinia consectetuer tellus leo.,12/2/14,487.02 Chloe Chen,antony@busybase.eu,,Quis,Tincidunt,Aliquam,7,E3862315-B49C-4EF6-B465-A93FF320A3EC,BTEBYEBS,Greenland,Et suscipit lectus nec morbi tristique mi in nunc tincidunt.,12/26/09,366.24 Andreas McCann,bjorn@jetwerk.hn,,Non,Ultrices,Congue,10,6F3B60E9-29B0-4421-8EF1-864C8318D20A,JPV00X2A,Estonia,Quis morbi eu sit mollis ad purus consectetuer consectetuer aliquam.,7/15/15,591.28 Owen Buckley,dragan.graves@quitdesk.cg,,Aliquam,Lacinia,Phasellus,6,52D97856-9714-4A13-9C64-A7E3028F3D64,HWH8ZXSN,"Saint Helena, Ascension and Tristan Da Cunha",Aliquam semper hac sit suspendisse mollis ligula volutpat sociosqu mi conubia porta lorem velit.,4/11/13,837.92 Damian Serrano,arnold.henderson@earlybeat.cz,,Aliquam,Lacinia,Phasellus,8,0D2E368D-83D4-4FCC-B583-F4F3750E8594,ICRKS93T,Hong Kong,Aliquet ante dui nec tempus a semper nisi non porttitor nisi magna cursus tellus facilisis cras massa.,11/30/10,856.89 Vicky Petty,tobias@tagbase.hk,,Accumsan,Lacinia,Enim,9,0A3AF79E-C848-4B7D-9B3E-AAD853908643,MC7RH905,Bahrain,Metus imperdiet suspendisse velit integer consectetuer purus per quisque.,11/19/15,285.9 Reginald Wong,adrian@fuellive.hu,,Et,In,Non,5,DAC224E4-858F-4824-9AB4-B32F8CAAD4B5,VRNKD7KV,Nicaragua,Class vulputate amet semper duis taciti libero morbi etiam tortor primis.,8/15/12,287.21 Belinda Gillespie,claudio.potts@rollblog.nz,,A,Consectetuer,Hac,10,699E97C0-9631-4207-9123-51990D860E54,ABWLPV48,Albania,Hac sociosqu ad lacinia bibendum sed rutrum sodales diam nisl mauris et quisque.,2/20/11,141.62 Isidro Kelly,guillermo@madewerk.ca,,Tristique,Sit,Mollis,10,B2E06E00-E797-4082-878F-0A584B583267,ORVTFDS1,Japan,Quis leo porta dui mi mattis enim ligula lectus tincidunt scelerisque dolor a quis libero venenatis class.,4/2/15,936.24 Kris Carlson,ballard@getserv.nr,,Elit,Quam,Magna,5,3D3B156A-C8E5-4F44-8271-231E5647234A,WYPZ7TL0,Cuba,Diam eu tellus curabitur augue mollis volutpat dictumst tellus non tempor non ultrices nostra egestas.,1/8/12,945.01 Ivo May,ilia.dunlap@rollsource.af,,Gravida,Mauris,Vivamus,9,033374F0-E202-4DD4-8909-3A376E94AAE3,AIMB2QVF,Paraguay,Ornare sem purus ad sapien egestas vulputate nec.,11/16/15,735.17 Valery Bailey,jenkins@tagclicks.gt,,Magna,Ante,Erat,8,8405FCDC-423C-4780-85A2-763B76F8E3E6,MTKQNQQ1,United States,Pellentesque sit curabitur cras felis eu ipsum sapien mattis suspendisse taciti tellus bibendum nulla nec.,9/20/14,871.22 Edna Hunt,huynh@busybase.sh,,Aliquam,Lacinia,Phasellus,9,CDD32EE0-5C1B-43E0-AD2C-AC70A7E49A5F,6PLCX7HA,Israel,Magna interdum lectus lacus ac pede duis class donec auctor tristique pulvinar aliquam adipiscing.,6/22/13,579.79 Debbie Padilla,anderson@fussbit.do,,Aliquam,Lacinia,Phasellus,6,1AE18842-F09E-4080-B269-B2222E265A07,L9JOMH1V,Pitcairn,Elementum nibh arcu mauris lacus nisl magnis nibh sollicitudin ligula proin.,4/12/14,821.68 Michael Carlson,russell.blake@tagserv.tt,,Dui,Justo,Vitae,8,184393AC-818C-411F-9835-382556AF6699,A2I31GTM,Canada,Sollicitudin id massa consectetuer at mauris ipsum amet sapien.,5/23/15,654.99 Jay Marsh,jorgen@putbase.mz,,Curae,Mollis,Elit,6,869A8F25-968F-4D02-A19F-765FE6AE8C84,0Z95CGIA,"Tanzania, United Republic of",Varius lacinia in nunc sit placerat posuere inceptos nibh.,11/27/15,694.94 Lawrence Golden,clay@jetlive.ms,,Consequat,Nibh,Nisi,8,178AEFF6-3CC9-4696-A819-2EDFBEF029D4,KL16BDUD,Afghanistan,Lorem a nisi nibh est tempor a etiam gravida neque pellentesque pharetra condimentum metus suspendisse at.,1/16/13,923.12 Jean Paul Mayer,salazar@shutsphere.fo,,Sit,Aliquam,Nunc,10,6D3F66BE-5AA1-4433-B6A9-340D84EAB6A9,V44K0F6X,Chile,Duis eu aliquam massa lorem aptent ligula eleifend vivamus mollis malesuada ac fusce est massa nostra non.,3/18/12,433.79 Kieran McIntyre,daisy.dunlap@selfware.ca,,Proin,Cursus,Justo,9,745D1136-623A-4AEE-A884-4689614CD977,4Y0JJQTL,French Southern Territories,Nibh sodales nulla adipiscing congue turpis facilisis eu quis libero cursus.,1/11/15,671.09 Amy Singleton,almir.carson@putunit.gn,,Litora,Quis,Nulla,10,FA7D5D32-9815-4073-93A3-50F1E82967B5,FLS5TGG8,Trinidad and Tobago,Mus elit in posuere nibh tincidunt sociis aliquet tristique morbi at imperdiet turpis.,11/20/10,794.63 Justine Buck,sharon@tidyware.nf,,Bibendum,Nunc,Massa,10,963FF749-90F2-4801-AB9C-C3B7D8331175,HKWWK3Z6,Niue,Mauris nibh sed et suspendisse mauris ante vestibulum a ullamcorper elit quis.,5/21/15,398.93 Clifton Watkins,jane.montoya@fuelblog.my,,Id,Duis,Viverra,5,419B9D22-5C4E-47CF-B390-C42A8BC95C1C,ZF8AA2X0,"Virgin Islands, British",Suscipit nec consequat tortor a nonummy commodo lacus cras nisi.,10/9/10,772.13 Javier Goodman,debbie@rollclicks.in,,Egestas,Mauris,Accumsan,6,AADE6BB0-0BEE-42FB-B8F7-C882C42830CD,OCT4I7OC,"Bolivia, Plurinational State of",Mi est arcu aliquet feugiat mi torquent magna massa at et vel hymenaeos in accumsan.,1/12/14,238.17 Andreas Cross,sarah@mybit.edu,,Lacinia,Ullamcorper,Torquent,9,FFD22AD7-3A9C-499F-AB28-7595CD0B91FB,7OSLH34U,Mauritius,Aptent bibendum ultrices scelerisque interdum ad ut tempor rhoncus pellentesque mi vulputate velit ligula sem.,7/22/11,837.99 Michael Hudson,brett@getblog.ga,,Iaculis,Consectetuer,Duis,6,7ED1518C-FD51-4535-A0EA-61A317B329B2,BQRCDS5G,Antigua and Barbuda,Lorem egestas malesuada non tellus eu felis et id eget.,10/25/10,898.36 Travis Sullivan,ayala@earlywerk.bo,,Sapien,Et,Ipsum,8,6C770379-4788-4D52-9A22-9C13B5E382C6,00Z8ZH9Q,Montserrat,Quam condimentum imperdiet massa eu cras senectus et elit et pharetra sem donec lectus.,10/7/10,642.34 \ No newline at end of file +Name,Email,Username,Asset Name,Asset Category,Asset Model,Manufacturer,Asset Model Number,Asset Serial,Asset Tag,Location Name,Asset Notes,Purchase Date,Purchase Cost William Dixon,miranda@selfware.ch,,Bleghjgd,Malesuada,Et,Nisi,5,4D47A5B7-007D-47F3-B1F2-28C33D3F2C54,58SG1MLI,"Tanzania, United Republic of",Accumsan condimentum sed purus ante mauris tincidunt aliquam libero tempor arcu posuere curabitur sodales imperdiet.,2/16/13,892.46 Debbie Mullins,jesper@madefeed.cf,,KJhkjfhk,At,Platea,Torquent,9,6DEC0B69-32DB-4801-81FA-07C58E5386CC,FIM4P54T,Isle of Man,Sodales enim duis egestas turpis arcu justo aliquam ipsum erat in cursus iaculis taciti nullam.,4/12/10,961.03 Wolfgang Mitchell,kirk@tagbase.kp,,,Id,Vel,Eu,5,D4017718-D68C-40EC-8669-52745A34B048,SY4NFU7S,Cook Islands,Ac platea nunc nibh in nibh eu arcu eu felis congue nibh aenean morbi quis scelerisque.,4/29/14,771.68 Anne-Marie Wallace,le@tidything.ac,,,Morbi,Sociosqu,Nisl,5,56CC5079-F44B-4D62-BC45-1A4CA4FB8C9F,SK6VTSTG,Uruguay,Nostra ut mauris consectetuer donec scelerisque est per pellentesque nec id urna magna.,8/18/14,325.22 Shane Booker,alain@quitsource.pa,,,Fusce,Fermentum,Sagittis,7,ED248E82-046B-4046-84DA-E4F4A0B55D0E,DBEUH6H2,Cura’_ao,Sed magna inceptos fames ultrices per ut eleifend tellus in class.,10/12/12,951.21 Olivier Walter,margaret@quitbot.tf,,,Malesuada,Et,Nisi,6,FC741D83-3F19-4259-94EC-FFAB3C15C747,40SI9NUR,El Salvador,Orci tortor sed vestibulum nec imperdiet vivamus ridiculus feugiat neque ut pellentesque felis.,8/14/11,368.9 Adrian Montgomery,welch@busybeat.kp,,,Malesuada,Et,Nisi,6,E8E3709B-377E-4FC7-B1B7-1DE0EE60798B,LUXLI88S,Bosnia and Herzegovina,Dapibus scelerisque tempor nisl nascetur dictum vulputate mi.,9/2/13,276.77 Joan Merrill,massey@jetwords.at,,,Malesuada,Et,Nisi,6,3D862DC2-74B5-4744-8D8B-41A757927EB8,ENAZFLV3,Tonga,Malesuada felis accumsan gravida sagittis lacinia pede orci nulla magna litora augue orci.,8/31/14,123.23 Stella Gilmore,wright@quitsource.jp,,,Malesuada,Et,Nisi,5,1E420152-929A-4363-8864-7DE01D38BDE0,8JS4P5P2,Uruguay,Magna in interdum consectetuer consequat tristique dapibus class nulla quis massa dictumst ipsum imperdiet.,4/22/12,333.44 Georgina Wiley,rivera@lowwerk.lv,,,Urna,Et,Integer,10,6E668691-2560-4E3D-89D4-1CDB7404BB8F,J3KHF9EK,Georgia,Consequat non per viverra porta torquent in non et suspendisse bibendum scelerisque sapien mi elit nostra imperdiet.,12/16/14,588.07 Barry Hudson,jane@tagbot.tc,,,Nam,Vivamus,Nibh,5,26825937-9579-4B57-9678-0659A2BB75D7,1V1WQAZA,Poland,Molestie tortor posuere duis lacus feugiat nibh mollis pellentesque nibh mollis tincidunt nisl ut inceptos ac pretium.,4/7/13,839.61 Leigh Stewart,jim.douglas@quitpower.si,,LKfjlgjlf klj,In,Mauris,Et,9,F5A3666A-951B-46FD-84AF-C0B36BE34243,8PU2UCVH,Uzbekistan,Praesent lectus amet fusce a aliquet pellentesque justo etiam vulputate nec.,3/17/14,724.88 Travis Flynn,nigel.blackburn@gigabase.md,,,Nonummy,Mattis,Justo,7,008A88C0-355D-40F9-B601-7478901147E4,8O77P76Z,Hungary,Massa suscipit porta sapien purus quis metus quis vivamus curae; suspendisse ut imperdiet dapibus.,4/3/12,625.79 Edward Park,sanders@madeclicks.travel,,,Nonummy,Mattis,Justo,9,228F09D4-F8A4-4453-BD7F-6FDB4FCFCE0A,FNKJCPIY,Uzbekistan,Neque eu non a felis enim turpis eget mauris lorem.,6/22/12,122.28 Stig Molina,lester@getdesk.at,,,Nonummy,Mattis,Justo,9,BA720380-E958-4D09-8EF2-D5B6FDF0736C,C4DXBUKJ,Georgia,Mollis ut sapien in id pede gravida ante eu nisl aenean ullamcorper potenti nulla parturient nam quisque.,7/10/13,178.12 Bruce Watts,ali.hobbs@gigawerk.gu,,,Nonummy,Mattis,Justo,7,2AF6BE26-EB5F-4745-8822-D54B3536EF9E,W9PO94OR,Finland,Ante facilisis ullamcorper eleifend enim quam justo vestibulum.,8/26/15,583.97 Lincoln Soto,michelle.daniel@presssource.sk,,,Nonummy,Mattis,Justo,5,913AEF6D-547C-41DD-9128-2A6FEF5E5118,9DOEWENU,Benin,Sociis aptent ipsum leo sodales mattis leo sociosqu at amet ligula.,6/22/11,581.01 Camilla Morrison,charles@chatspace.th,,,Ad,Elit,Ullamcorper,7,2ACA4B3C-A619-48AF-9530-8B581E5F9DBA,2AF7QYGX,Uzbekistan,Molestie quis placerat magna turpis iaculis eget nam massa sit congue erat hac habitant lacinia nibh.,2/28/15,492.81 Josie English,stafford@rollthing.nf,,,Eu,Aliquam,Enim,7,34302A6E-CB8F-4691-9D9B-845887D0F5B2,Q7ALASVU,Botswana,Rhoncus hymenaeos sed torquent vestibulum nec mauris id nulla nibh purus purus donec vel nibh morbi.,7/15/13,441.14 Alia Salazar,johan.cook@pressbit.ai,,,Ipsum,Velit,Magna,9,E429BE64-8E1B-4C8F-BB31-C4B2F2754C3C,HKZ2HG9E,New Caledonia,Sed praesent sed rutrum massa suscipit magna mauris interdum massa.,3/28/13,384.99 Beth Sweeney,coral.le@chatsource.dj,,,Ipsum,Velit,Magna,8,3FC9CF5F-EBCC-4482-8F0D-7F99EE2911A4,UM5HO5SD,Vanuatu,Aliquet porttitor elit sagittis mauris nibh rutrum tristique nunc erat mauris per integer nostra imperdiet.,9/2/15,575.23 Stig Bender,lydia@rollsimple.tp,,,Ipsum,Velit,Magna,9,A39EB068-99C6-4377-AB3F-CACC83E083D1,NHYLZ75J,Burundi,Lobortis morbi massa praesent eu ac ad ut nunc aliquam neque scelerisque est fermentum eget elit aenean.,11/29/09,277.87 Angelique Lindsay,villarreal@selfserv.sg,,,Ipsum,Velit,Magna,6,EA864247-21AF-44C9-96CC-D6900C599740,PZ9MMXYD,Lithuania,Id eu molestie adipiscing phasellus duis imperdiet aliquam conubia ligula eget morbi.,8/14/14,552.75 Guillermo Black,raimonds@gigadesk.bd,,,Id,Class,Laoreet,5,543C547F-91CD-4AFD-AFBF-2E2B68FD514D,M3VRKBBJ,Equatorial Guinea,Egestas pretium sollicitudin suspendisse erat sem massa adipiscing eu tempor libero sollicitudin a curabitur mauris.,1/1/14,582.02 Christof Castaneda,campos@fuelserv.bg,,,Eget,Congue,Nisi,6,CAB3E433-8409-475C-8EA0-2801C22B2C2B,B0CGYUG7,Syrian Arab Republic,Feugiat facilisis consequat sociosqu ac consequat lacinia consectetuer tellus leo.,12/2/14,487.02 Chloe Chen,antony@busybase.eu,,,Quis,Tincidunt,Aliquam,7,E3862315-B49C-4EF6-B465-A93FF320A3EC,BTEBYEBS,Greenland,Et suscipit lectus nec morbi tristique mi in nunc tincidunt.,12/26/09,366.24 Andreas McCann,bjorn@jetwerk.hn,,,Non,Ultrices,Congue,10,6F3B60E9-29B0-4421-8EF1-864C8318D20A,JPV00X2A,Estonia,Quis morbi eu sit mollis ad purus consectetuer consectetuer aliquam.,7/15/15,591.28 Owen Buckley,dragan.graves@quitdesk.cg,,,Aliquam,Lacinia,Phasellus,6,52D97856-9714-4A13-9C64-A7E3028F3D64,HWH8ZXSN,"Saint Helena, Ascension and Tristan Da Cunha",Aliquam semper hac sit suspendisse mollis ligula volutpat sociosqu mi conubia porta lorem velit.,4/11/13,837.92 Damian Serrano,arnold.henderson@earlybeat.cz,,,Aliquam,Lacinia,Phasellus,8,0D2E368D-83D4-4FCC-B583-F4F3750E8594,ICRKS93T,Hong Kong,Aliquet ante dui nec tempus a semper nisi non porttitor nisi magna cursus tellus facilisis cras massa.,11/30/10,856.89 Vicky Petty,tobias@tagbase.hk,,,Accumsan,Lacinia,Enim,9,0A3AF79E-C848-4B7D-9B3E-AAD853908643,MC7RH905,Bahrain,Metus imperdiet suspendisse velit integer consectetuer purus per quisque.,11/19/15,285.9 Reginald Wong,adrian@fuellive.hu,,,Et,In,Non,5,DAC224E4-858F-4824-9AB4-B32F8CAAD4B5,VRNKD7KV,Nicaragua,Class vulputate amet semper duis taciti libero morbi etiam tortor primis.,8/15/12,287.21 Belinda Gillespie,claudio.potts@rollblog.nz,,,A,Consectetuer,Hac,10,699E97C0-9631-4207-9123-51990D860E54,ABWLPV48,Albania,Hac sociosqu ad lacinia bibendum sed rutrum sodales diam nisl mauris et quisque.,2/20/11,141.62 Isidro Kelly,guillermo@madewerk.ca,,,Tristique,Sit,Mollis,10,B2E06E00-E797-4082-878F-0A584B583267,ORVTFDS1,Japan,Quis leo porta dui mi mattis enim ligula lectus tincidunt scelerisque dolor a quis libero venenatis class.,4/2/15,936.24 Kris Carlson,ballard@getserv.nr,,,Elit,Quam,Magna,5,3D3B156A-C8E5-4F44-8271-231E5647234A,WYPZ7TL0,Cuba,Diam eu tellus curabitur augue mollis volutpat dictumst tellus non tempor non ultrices nostra egestas.,1/8/12,945.01 Ivo May,ilia.dunlap@rollsource.af,,,Gravida,Mauris,Vivamus,9,033374F0-E202-4DD4-8909-3A376E94AAE3,AIMB2QVF,Paraguay,Ornare sem purus ad sapien egestas vulputate nec.,11/16/15,735.17 Valery Bailey,jenkins@tagclicks.gt,,,Magna,Ante,Erat,8,8405FCDC-423C-4780-85A2-763B76F8E3E6,MTKQNQQ1,United States,Pellentesque sit curabitur cras felis eu ipsum sapien mattis suspendisse taciti tellus bibendum nulla nec.,9/20/14,871.22 Edna Hunt,huynh@busybase.sh,,,Aliquam,Lacinia,Phasellus,9,CDD32EE0-5C1B-43E0-AD2C-AC70A7E49A5F,6PLCX7HA,Israel,Magna interdum lectus lacus ac pede duis class donec auctor tristique pulvinar aliquam adipiscing.,6/22/13,579.79 Debbie Padilla,anderson@fussbit.do,,,Aliquam,Lacinia,Phasellus,6,1AE18842-F09E-4080-B269-B2222E265A07,L9JOMH1V,Pitcairn,Elementum nibh arcu mauris lacus nisl magnis nibh sollicitudin ligula proin.,4/12/14,821.68 Michael Carlson,russell.blake@tagserv.tt,,,Dui,Justo,Vitae,8,184393AC-818C-411F-9835-382556AF6699,A2I31GTM,Canada,Sollicitudin id massa consectetuer at mauris ipsum amet sapien.,5/23/15,654.99 Jay Marsh,jorgen@putbase.mz,,,Curae,Mollis,Elit,6,869A8F25-968F-4D02-A19F-765FE6AE8C84,0Z95CGIA,"Tanzania, United Republic of",Varius lacinia in nunc sit placerat posuere inceptos nibh.,11/27/15,694.94 Lawrence Golden,clay@jetlive.ms,,,Consequat,Nibh,Nisi,8,178AEFF6-3CC9-4696-A819-2EDFBEF029D4,KL16BDUD,Afghanistan,Lorem a nisi nibh est tempor a etiam gravida neque pellentesque pharetra condimentum metus suspendisse at.,1/16/13,923.12 Jean Paul Mayer,salazar@shutsphere.fo,,,Sit,Aliquam,Nunc,10,6D3F66BE-5AA1-4433-B6A9-340D84EAB6A9,V44K0F6X,Chile,Duis eu aliquam massa lorem aptent ligula eleifend vivamus mollis malesuada ac fusce est massa nostra non.,3/18/12,433.79 Kieran McIntyre,daisy.dunlap@selfware.ca,,,Proin,Cursus,Justo,9,745D1136-623A-4AEE-A884-4689614CD977,4Y0JJQTL,French Southern Territories,Nibh sodales nulla adipiscing congue turpis facilisis eu quis libero cursus.,1/11/15,671.09 Amy Singleton,almir.carson@putunit.gn,,,Litora,Quis,Nulla,10,FA7D5D32-9815-4073-93A3-50F1E82967B5,FLS5TGG8,Trinidad and Tobago,Mus elit in posuere nibh tincidunt sociis aliquet tristique morbi at imperdiet turpis.,11/20/10,794.63 Justine Buck,sharon@tidyware.nf,,,Bibendum,Nunc,Massa,10,963FF749-90F2-4801-AB9C-C3B7D8331175,HKWWK3Z6,Niue,Mauris nibh sed et suspendisse mauris ante vestibulum a ullamcorper elit quis.,5/21/15,398.93 Clifton Watkins,jane.montoya@fuelblog.my,,,Id,Duis,Viverra,5,419B9D22-5C4E-47CF-B390-C42A8BC95C1C,ZF8AA2X0,"Virgin Islands, British",Suscipit nec consequat tortor a nonummy commodo lacus cras nisi.,10/9/10,772.13 Javier Goodman,debbie@rollclicks.in,,,Egestas,Mauris,Accumsan,6,AADE6BB0-0BEE-42FB-B8F7-C882C42830CD,OCT4I7OC,"Bolivia, Plurinational State of",Mi est arcu aliquet feugiat mi torquent magna massa at et vel hymenaeos in accumsan.,1/12/14,238.17 Andreas Cross,sarah@mybit.edu,,,Lacinia,Ullamcorper,Torquent,9,FFD22AD7-3A9C-499F-AB28-7595CD0B91FB,7OSLH34U,Mauritius,Aptent bibendum ultrices scelerisque interdum ad ut tempor rhoncus pellentesque mi vulputate velit ligula sem.,7/22/11,837.99 Michael Hudson,brett@getblog.ga,,,Iaculis,Consectetuer,Duis,6,7ED1518C-FD51-4535-A0EA-61A317B329B2,BQRCDS5G,Antigua and Barbuda,Lorem egestas malesuada non tellus eu felis et id eget.,10/25/10,898.36 Travis Sullivan,ayala@earlywerk.bo,,,Sapien,Et,Ipsum,8,6C770379-4788-4D52-9A22-9C13B5E382C6,00Z8ZH9Q,Montserrat,Quam condimentum imperdiet massa eu cras senectus et elit et pharetra sem donec lectus.,10/7/10,642.34 \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index d872f6e214..11bbc67137 100755 --- a/app/routes.php +++ b/app/routes.php @@ -28,7 +28,11 @@ } else { return '0'; } - } ); + + }); + + Route::get( 'list', [ 'as' => 'api.statuslabels.list', 'uses' => 'StatuslabelsController@getDatatable' ] ); + } ); /*---Accessories API---*/ @@ -40,12 +44,31 @@ } ); /*---Consumables API---*/ - Route::group( [ 'prefix' => 'consumables' ], function () { + Route::group(array('prefix'=>'consumables'), function () { + Route::get('list', array('as'=>'api.consumables.list', 'uses'=>'ConsumablesController@getDatatable')); + Route::get('{consumableID}/view', array('as'=>'api.consumables.view', 'uses'=>'ConsumablesController@getDataView')); + }); - Route::get( 'list', [ 'as' => 'api.consumables.list', 'uses' => 'ConsumablesController@getDatatable' ] ); - Route::get( '{accessoryID}/view', - [ 'as' => 'api.consumables.view', 'uses' => 'ConsumablesController@getDataView' ] ); - } ); + /*---Locations API---*/ + Route::group(array('prefix'=>'locations'), function () { + Route::get('list', array('as'=>'api.locations.list', 'uses'=>'LocationsController@getDatatable')); + }); + + /*---Depreciations API---*/ + Route::group(array('prefix'=>'depreciations'), function () { + Route::get('list', array('as'=>'api.depreciations.list', 'uses'=>'DepreciationsController@getDatatable')); + Route::get('{$depreciationID}/view', array('as'=>'api.depreciations.view', 'uses'=>'DepreciationsController@getDataView')); + }); + + /*---Manufacturers API---*/ + Route::group(array('prefix'=>'manufacturers'), function () { + Route::get('list', array('as'=>'api.manufacturers.list', 'uses'=>'ManufacturersController@getDatatable')); + }); + + /*---Suppliers API---*/ + Route::group(array('prefix'=>'suppliers'), function () { + Route::get('list', array('as'=>'api.suppliers.list', 'uses'=>'SuppliersController@getDatatable')); + }); /*---Users API---*/ Route::group( [ 'prefix' => 'users' ], function () { diff --git a/app/views/backend/accessories/edit.blade.php b/app/views/backend/accessories/edit.blade.php index c2880ae31e..02ce60e0f0 100755 --- a/app/views/backend/accessories/edit.blade.php +++ b/app/views/backend/accessories/edit.blade.php @@ -58,6 +58,45 @@ {{ $errors->first('category_id', ' :message') }} + + +
+
+ {{ Form::label('order_number', Lang::get('admin/accessories/general.order')) }} +
+
+ + {{ $errors->first('order_number', '
:message') }} +
+
+ + +
+
+ {{ Form::label('purchase_date', Lang::get('admin/accessories/general.date')) }} +
+
+ + + {{ $errors->first('purchase_date', '
:message') }} +
+
+ + +
+
+ {{ Form::label('purchase_cost', Lang::get('admin/accessories/general.cost')) }} +
+
+
+ + {{{ Setting::first()->default_currency }}} + + + {{ $errors->first('purchase_cost', '
:message') }} +
+
+
@@ -66,8 +105,8 @@
-
- +
+
{{ $errors->first('qty', ' :message') }}
diff --git a/app/views/backend/accessories/index.blade.php b/app/views/backend/accessories/index.blade.php index 5c84daab80..7837d93aee 100755 --- a/app/views/backend/accessories/index.blade.php +++ b/app/views/backend/accessories/index.blade.php @@ -19,80 +19,26 @@
+ +@section('moar_scripts') + + + + + + + +@stop + + @stop diff --git a/app/views/backend/accessories/view.blade.php b/app/views/backend/accessories/view.blade.php index a5cee39394..62191f2ef5 100644 --- a/app/views/backend/accessories/view.blade.php +++ b/app/views/backend/accessories/view.blade.php @@ -25,62 +25,26 @@ + + +
+
+ {{ Form::label('order_number', Lang::get('admin/consumables/general.order')) }} +
+
+ + {{ $errors->first('order_number', '
:message') }} +
+
+ + +
+
+ {{ Form::label('purchase_date', Lang::get('admin/consumables/general.date')) }} +
+
+ + + {{ $errors->first('purchase_date', '
:message') }} +
+
+ + +
+
+ {{ Form::label('purchase_cost', Lang::get('admin/consumables/general.cost')) }} +
+
+
+ + {{{ Setting::first()->default_currency }}} + + + {{ $errors->first('purchase_cost', '
:message') }} +
+
+
@@ -66,8 +105,8 @@
-
- +
+
{{ $errors->first('qty', ' :message') }}
diff --git a/app/views/backend/consumables/index.blade.php b/app/views/backend/consumables/index.blade.php index 70f23c4295..22d5fb0849 100644 --- a/app/views/backend/consumables/index.blade.php +++ b/app/views/backend/consumables/index.blade.php @@ -19,78 +19,22 @@
+ +@section('moar_scripts') + + + + + + + + +@stop + @stop diff --git a/app/views/backend/consumables/view.blade.php b/app/views/backend/consumables/view.blade.php index 68243c2699..48302d2853 100644 --- a/app/views/backend/consumables/view.blade.php +++ b/app/views/backend/consumables/view.blade.php @@ -27,56 +27,41 @@ @stop diff --git a/app/views/backend/hardware/index.blade.php b/app/views/backend/hardware/index.blade.php index 1daacb59bd..9064dae602 100755 --- a/app/views/backend/hardware/index.blade.php +++ b/app/views/backend/hardware/index.blade.php @@ -33,10 +33,6 @@ {{-- Page content --}} @section('content') -
@@ -47,87 +43,113 @@
- - {{ Form::open([ 'method' => 'POST', 'route' => ['hardware/bulkedit'], 'class' => 'form-horizontal' ]) }} + + + - -{{ Datatable::table() - ->addColumn('
',Lang::get('admin/hardware/form.name'), - Lang::get('admin/hardware/table.asset_tag'), - Lang::get('admin/hardware/table.serial'), - Lang::get('admin/hardware/form.model'), - Lang::get('admin/hardware/table.status'), - Lang::get('admin/hardware/table.location'), - Lang::get('general.category'), - Lang::get('admin/hardware/table.eol'), - Lang::get('general.notes'), - "REMOVEME", - Lang::get('admin/hardware/form.order'), - Lang::get('admin/hardware/table.checkout_date'), - Lang::get('admin/hardware/table.change'), - Lang::get('table.actions')) - ->setOptions( - array( - 'language' => array( - 'search' => Lang::get('general.search'), - 'lengthMenu' => Lang::get('general.page_menu'), - 'loadingRecords' => Lang::get('general.loading'), - 'zeroRecords' => Lang::get('general.no_results'), - 'info' => Lang::get('general.pagination_info'), - 'processing' => ' '.Lang::get('general.processing'), - 'paginate'=> array( - 'first'=>Lang::get('general.first'), - 'previous'=>Lang::get('general.previous'), - 'next'=>Lang::get('general.next'), - 'last'=>Lang::get('general.last'), - ), - ), - 'sAjaxSource'=> route('api.hardware.list', array(''=>Input::get('status'),'order_number'=>Input::get('order_number'))), - 'dom' =>'CT<"clear">lfrtip', - 'colVis'=> array('showAll'=>'Show All','restore'=>'Restore','exclude'=>array(0,12,13),'activate'=>'mouseover'), - 'columnDefs'=> array(array('visible'=>false,'targets'=>array(7,8,9)),array('orderable'=>false,'targets'=>array(0,12,13))), - 'order'=>array(array(1,'asc')), - ) - ) - ->render('backend/hardware/datatable') }} - + + + + + + + + + + + + + + + + + + + + + + +
@lang('general.id'){{Lang::get('admin/hardware/form.name')}}{{Lang::get('admin/hardware/table.asset_tag')}}{{Lang::get('admin/hardware/table.serial')}}{{Lang::get('admin/hardware/form.model')}}{{Lang::get('admin/hardware/table.status')}}{{Lang::get('admin/hardware/table.location')}}{{Lang::get('general.category')}}{{Lang::get('general.eol')}}{{Lang::get('general.notes')}}{{Lang::get('admin/hardware/form.order')}}{{Lang::get('admin/hardware/table.checkout_date')}}{{Lang::get('admin/hardware/table.change')}}{{Lang::get('table.actions')}}
+ + +
{{ Form::close() }} -
- + + + + + + + +@stop @stop diff --git a/app/views/backend/hardware/view.blade.php b/app/views/backend/hardware/view.blade.php index 71707ac047..2fc090a6ff 100755 --- a/app/views/backend/hardware/view.blade.php +++ b/app/views/backend/hardware/view.blade.php @@ -9,6 +9,7 @@ {{-- Page content --}} @section('content') +

@@ -99,10 +100,12 @@ @endif @if ($asset->supplier_id) -
@lang('admin/hardware/form.supplier'): - - {{{ $asset->supplier->name }}} -
+
+ @lang('admin/hardware/form.supplier'): + + {{{ $asset->supplier->name }}} + +
@endif @if ($asset->warranty_months) @@ -286,7 +289,13 @@ @endif - {{{ $file->filename }}} + @if (Asset::checkUploadIsImage($file->get_src())) + {{{ $file->filename }}} + @else + {{{ $file->filename }}} + @endif + + @if ($file->filename) @@ -311,6 +320,8 @@

+ +
History
@@ -378,6 +389,7 @@
+ @if ($asset->notes) @@ -511,5 +523,16 @@
+@section('moar_scripts') + +@stop @stop diff --git a/app/views/backend/layouts/default.blade.php b/app/views/backend/layouts/default.blade.php index 7f3186369f..5857440d13 100644 --- a/app/views/backend/layouts/default.blade.php +++ b/app/views/backend/layouts/default.blade.php @@ -36,19 +36,16 @@ - - - + + - - - - + + - + + @section('moar_scripts') + @show + diff --git a/app/views/backend/licenses/index.blade.php b/app/views/backend/licenses/index.blade.php index 9f5bc61f5b..22281a6858 100755 --- a/app/views/backend/licenses/index.blade.php +++ b/app/views/backend/licenses/index.blade.php @@ -17,42 +17,67 @@
- {{ Datatable::table() - ->addColumn(Lang::get('admin/licenses/table.title'), - Lang::get('admin/licenses/table.serial'), - Lang::get('admin/licenses/form.to_name'), - Lang::get('admin/licenses/form.to_email'), - Lang::get('admin/licenses/form.seats'), - Lang::get('admin/licenses/form.remaining_seats'), - Lang::get('admin/licenses/table.purchase_date'), - Lang::get('admin/licenses/form.notes'), - Lang::get('table.actions')) - ->setOptions( - array( - 'language' => array( - 'search' => Lang::get('general.search'), - 'lengthMenu' => Lang::get('general.page_menu'), - 'loadingRecords' => Lang::get('general.loading'), - 'zeroRecords' => Lang::get('general.no_results'), - 'info' => Lang::get('general.pagination_info'), - 'processing' => Lang::get('general.processing'), - 'paginate'=> array( - 'first'=>Lang::get('general.first'), - 'previous'=>Lang::get('general.previous'), - 'next'=>Lang::get('general.next'), - 'last'=>Lang::get('general.last'), - ), - ), - 'sAjaxSource'=>route('api.licenses.list'), - 'dom' =>'CT<"clear">lfrtip', - 'colVis'=> array('showAll'=>'Show All','restore'=>'Restore','exclude'=>array(8),'activate'=>'mouseover'), - 'columnDefs'=> array( - array('bSortable'=>false,'targets'=>array(8)), - array('width'=>'20%','targets'=>array(8)), - ), - 'order'=>array(array(0,'asc')), - ) - ) - ->render() }} +
+ + + + + + + + + + + +
@lang('general.id'){{Lang::get('admin/licenses/table.title')}}{{Lang::get('admin/licenses/table.serial')}}{{Lang::get('admin/licenses/form.seats')}}{{Lang::get('admin/licenses/form.remaining_seats')}}{{Lang::get('admin/licenses/table.purchase_date')}}{{Lang::get('table.actions')}}
+ +@section('moar_scripts') + + + + + + + + +@stop + @stop diff --git a/app/views/backend/locations/index.blade.php b/app/views/backend/locations/index.blade.php index f3d3d24fd4..3e15960c78 100755 --- a/app/views/backend/locations/index.blade.php +++ b/app/views/backend/locations/index.blade.php @@ -18,47 +18,73 @@ Locations ::
- - - - - - - - - - - - - @foreach ($locations as $location) - - - - - - - - - @endforeach - -
@lang('admin/locations/table.name')@lang('admin/locations/table.parent')@lang('general.assets')@lang('admin/locations/table.address')@lang('admin/locations/table.city'), - @lang('admin/locations/table.state') - @lang('admin/locations/table.country')@lang('table.actions')
{{{ $location->name }}} - @if ($location->parent) - {{{ $location->parent->name }}} - @endif - {{{ ($location->assets->count() + $location->assignedassets->count()) }}}{{{ $location->address }}} - @if($location->address2 != '') - , {{{ $location->address2 }}} - @endif - {{{ $location->city }}}, {{{ strtoupper($location->state) }}} {{{ strtoupper($location->country) }}} - - - -
+ + + + + + + + + + + + + + + +
@lang('general.id')@lang('admin/locations/table.name')@lang('admin/locations/table.parent')@lang('general.assets')@lang('general.currency')@lang('admin/locations/table.address')@lang('admin/locations/table.city') + + @lang('admin/locations/table.state') + + @lang('admin/locations/table.country'){{ Lang::get('table.actions') }}
+@section('moar_scripts') + + + + + + + +@stop @stop diff --git a/app/views/backend/manufacturers/index.blade.php b/app/views/backend/manufacturers/index.blade.php index c70445ab47..8b345ac2dd 100755 --- a/app/views/backend/manufacturers/index.blade.php +++ b/app/views/backend/manufacturers/index.blade.php @@ -22,32 +22,24 @@
- - - - - - - - - - @foreach ($manufacturers as $manufacturer) - - - - - - @endforeach - -
@lang('admin/manufacturers/table.name')@lang('general.assets')@lang('table.actions')
{{{ $manufacturer->name }}}{{ $manufacturer->assetscount() }} - - + + + + + + + + + +
@lang('general.id')@lang('admin/manufacturers/table.name')@lang('general.assets')@lang('table.actions')
- -
@@ -69,5 +61,46 @@
+@section('moar_scripts') + + + + + + + + +@stop @stop diff --git a/app/views/backend/models/index.blade.php b/app/views/backend/models/index.blade.php index 9695b6c0da..7ead7cb695 100755 --- a/app/views/backend/models/index.blade.php +++ b/app/views/backend/models/index.blade.php @@ -22,38 +22,56 @@
- {{ Datatable::table() - ->addColumn(Lang::get('general.manufacturer'), - Lang::get('admin/models/table.title'), - Lang::get('admin/models/table.modelnumber'), - Lang::get('admin/models/table.numassets'), - Lang::get('general.depreciation'), - Lang::get('general.category'), - Lang::get('general.eol'), - Lang::get('table.actions')) - ->setOptions( - array( - 'language' => array( - 'search' => Lang::get('general.search'), - 'lengthMenu' => Lang::get('general.page_menu'), - 'loadingRecords' => Lang::get('general.loading'), - 'zeroRecords' => Lang::get('general.no_results'), - 'info' => Lang::get('general.pagination_info'), - 'processing' => Lang::get('general.processing'), - 'paginate'=> array( - 'first'=>Lang::get('general.first'), - 'previous'=>Lang::get('general.previous'), - 'next'=>Lang::get('general.next'), - 'last'=>Lang::get('general.last'), - ), - ), - 'sAjaxSource'=> route('api.models.list', Input::get('status')), - 'dom' =>'CT<"clear">lfrtip', - 'colVis'=> array('showAll'=>'Show All','restore'=>'Restore','exclude'=>array(6),'activate'=>'mouseover'), - 'columnDefs'=> array(array('bSortable'=>false,'targets'=>array(6))), - 'order'=>array(array(0,'asc')), - ) - ) - ->render() }} + + + + + + + + + + + + + +
{{Lang::get('general.manufacturer')}}{{Lang::get('admin/models/table.title')}}{{Lang::get('admin/models/table.modelnumber')}}{{Lang::get('admin/models/table.numassets')}}{{Lang::get('general.depreciation')}}{{Lang::get('general.category')}}{{Lang::get('general.eol')}}{{ Lang::get('table.actions') }}
+ +@section('moar_scripts') + + + + + + + +@stop @stop diff --git a/app/views/backend/models/view.blade.php b/app/views/backend/models/view.blade.php index 215914ba2b..a5bc39fa78 100755 --- a/app/views/backend/models/view.blade.php +++ b/app/views/backend/models/view.blade.php @@ -52,25 +52,18 @@ @if (count($model->assets) > 0) - {{ Datatable::table() - ->addColumn(Lang::get('general.name'), - Lang::get('general.asset_tag'), - Lang::get('admin/hardware/table.serial'), - Lang::get('general.user'), - Lang::get('table.actions')) - ->setOptions( - array( - 'sAjaxSource'=>route('api.models.view', $model->id), - 'dom' =>'CT<"clear">lfrtip', - 'colVis'=> array('showAll'=>'Show All','restore'=>'Restore','exclude'=>array(4),'activate'=>'mouseover'), - 'columnDefs'=> array( - array('bSortable'=>false,'targets'=>array(4)), - array('width'=>'auto','targets'=>array(4)), - ), - 'order'=>array(array(0,'asc')), - ) - ) - ->render() }} + + + + + + + + + + + +
{{Lang::get('general.name')}}{{Lang::get('general.asset_tag')}}{{Lang::get('admin/hardware/table.serial')}}{{Lang::get('general.user')}}{{ Lang::get('table.actions') }}
@else
@@ -80,6 +73,7 @@
@endif +
diff --git a/app/views/backend/reports/activity.blade.php b/app/views/backend/reports/activity.blade.php index f3a39fa6a4..77edc00868 100644 --- a/app/views/backend/reports/activity.blade.php +++ b/app/views/backend/reports/activity.blade.php @@ -19,15 +19,15 @@
- +
- - - - - @lang('general.action') + + + + diff --git a/app/views/backend/settings/edit.blade.php b/app/views/backend/settings/edit.blade.php index fa522defba..c41b7729b4 100755 --- a/app/views/backend/settings/edit.blade.php +++ b/app/views/backend/settings/edit.blade.php @@ -2,333 +2,298 @@ {{-- Page title --}} @section('title') - @lang('admin/settings/general.update') :: +@lang('admin/settings/general.update') :: @parent @stop {{-- Page content --}} @section('content') +
+
+ @lang('general.back') +

@lang('admin/settings/general.update')

+
+
- + - + @if ($setting->load_remote == 1) diff --git a/app/views/backend/statuslabels/index.blade.php b/app/views/backend/statuslabels/index.blade.php index b34b7887dd..c40df384fb 100755 --- a/app/views/backend/statuslabels/index.blade.php +++ b/app/views/backend/statuslabels/index.blade.php @@ -21,44 +21,23 @@
-
- - -
@lang('general.admin')@lang('general.action')@lang('general.type')@lang('general.item')@lang('general.date')@lang('general.type')@lang('general.item')@lang('general.user')@lang('general.date')
@lang('admin/settings/general.load_remote')@lang('admin/settings/general.load_remote_text')@lang('general.yes')
- - - - - - - - - @foreach ($statuslabels as $statuslabel) - - - - - - @endforeach - -
@lang('admin/statuslabels/table.name')@lang('admin/statuslabels/table.status_type')@lang('table.actions')
{{{ $statuslabel->name }}} - @if ($statuslabel->deployable == 1) - @lang('admin/statuslabels/table.deployable') - @elseif ($statuslabel->pending == 1) - @lang('admin/statuslabels/table.pending') - @elseif ($statuslabel->archived == 1) - @lang('admin/statuslabels/table.archived') - @else - @lang('admin/statuslabels/table.undeployable') - @endif - - - -
- -
+ + + + + + + + + +
@lang('general.id')@lang('admin/statuslabels/table.name')@lang('admin/statuslabels/table.status_type'){{ Lang::get('table.actions') }}
+
@@ -70,4 +49,46 @@
+ +@section('moar_scripts') + + + + + + + +@stop + @stop diff --git a/app/views/backend/suppliers/index.blade.php b/app/views/backend/suppliers/index.blade.php index 665f39597d..519e458a30 100755 --- a/app/views/backend/suppliers/index.blade.php +++ b/app/views/backend/suppliers/index.blade.php @@ -19,66 +19,70 @@ '); + html.push(''); + }); + html.push(''); + }); + + this.$header.html(html.join('')); + this.$header.find('th[data-field]').each(function (i) { + $(this).data(visibleColumns[$(this).data('field')]); + }); + this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) { + if (that.options.sortable && $(this).parent().data().sortable) { + that.onSort(event); + } + }); + + this.$header.children().children().off('keypress').on('keypress', function (event) { + if (that.options.sortable && $(this).data().sortable) { + var code = event.keyCode || event.which; + if (code == 13) { //Enter keycode + that.onSort(event); + } + } + }); + + if (!this.options.showHeader || this.options.cardView) { + this.$header.hide(); + this.$tableHeader.hide(); + this.$tableLoading.css('top', 0); + } else { + this.$header.show(); + this.$tableHeader.show(); + this.$tableLoading.css('top', this.$header.outerHeight() + 1); + // Assign the correct sortable arrow + this.getCaret(); + } + + this.$selectAll = this.$header.find('[name="btSelectAll"]'); + this.$container.off('click', '[name="btSelectAll"]') + .on('click', '[name="btSelectAll"]', function () { + var checked = $(this).prop('checked'); + that[checked ? 'checkAll' : 'uncheckAll'](); + }); + }; + + BootstrapTable.prototype.initFooter = function () { + if (!this.options.showFooter || this.options.cardView) { + this.$tableFooter.hide(); + } else { + this.$tableFooter.show(); + } + }; + + /** + * @param data + * @param type: append / prepend + */ + BootstrapTable.prototype.initData = function (data, type) { + if (type === 'append') { + this.data = this.data.concat(data); + } else if (type === 'prepend') { + this.data = [].concat(data).concat(this.data); + } else { + this.data = data || this.options.data; + } + + // Fix #839 Records deleted when adding new row on filtered table + if (type === 'append') { + this.options.data = this.options.data.concat(data); + } else if (type === 'prepend') { + this.options.data = [].concat(data).concat(this.options.data); + } else { + this.options.data = this.data; + } + + if (this.options.sidePagination === 'server') { + return; + } + this.initSort(); + }; + + BootstrapTable.prototype.initSort = function () { + var that = this, + name = this.options.sortName, + order = this.options.sortOrder === 'desc' ? -1 : 1, + index = $.inArray(this.options.sortName, this.header.fields); + + if (index !== -1) { + this.data.sort(function (a, b) { + if (that.header.sortNames[index]) { + name = that.header.sortNames[index]; + } + var aa = getItemField(a, name), + bb = getItemField(b, name), + value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]); + + if (value !== undefined) { + return order * value; + } + + // Fix #161: undefined or null string sort bug. + if (aa === undefined || aa === null) { + aa = ''; + } + if (bb === undefined || bb === null) { + bb = ''; + } + + // IF both values are numeric, do a numeric comparison + if ($.isNumeric(aa) && $.isNumeric(bb)) { + // Convert numerical values form string to float. + aa = parseFloat(aa); + bb = parseFloat(bb); + if (aa < bb) { + return order * -1; + } + return order; + } + + if (aa === bb) { + return 0; + } + + // If value is not a string, convert to string + if (typeof aa !== 'string') { + aa = aa.toString(); + } + + if (aa.localeCompare(bb) === -1) { + return order * -1; + } + + return order; + }); + } + }; + + BootstrapTable.prototype.onSort = function (event) { + var $this = event.type === "keypress" ? $(event.currentTarget) : $(event.currentTarget).parent(), + $this_ = this.$header.find('th').eq($this.index()); + + this.$header.add(this.$header_).find('span.order').remove(); + + if (this.options.sortName === $this.data('field')) { + this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc'; + } else { + this.options.sortName = $this.data('field'); + this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc'; + } + this.trigger('sort', this.options.sortName, this.options.sortOrder); + + $this.add($this_).data('order', this.options.sortOrder); + + // Assign the correct sortable arrow + this.getCaret(); + + if (this.options.sidePagination === 'server') { + this.initServer(this.options.silentSort); + return; + } + + this.initSort(); + this.initBody(); + }; + + BootstrapTable.prototype.initToolbar = function () { + var that = this, + html = [], + timeoutId = 0, + $keepOpen, + $search, + switchableCount = 0; + + this.$toolbar.html(''); + + if (typeof this.options.toolbar === 'string' || typeof this.options.toolbar === 'object') { + $(sprintf('
', this.options.toolbarAlign)) + .appendTo(this.$toolbar) + .append($(this.options.toolbar)); + } + + // showColumns, showToggle, showRefresh + html = [sprintf('
', + this.options.buttonsAlign, this.options.buttonsAlign)]; + + if (typeof this.options.icons === 'string') { + this.options.icons = calculateObjectValue(null, this.options.icons); + } + + if (this.options.showPaginationSwitch) { + html.push(sprintf(''); + } + + if (this.options.showRefresh) { + html.push(sprintf(''); + } + + if (this.options.showToggle) { + html.push(sprintf(''); + } + + if (this.options.showColumns) { + html.push(sprintf('
', + this.options.formatColumns()), + '', + '', + '
'); + } + + html.push('
'); + + // Fix #188: this.showToolbar is for extentions + if (this.showToolbar || html.length > 2) { + this.$toolbar.append(html.join('')); + } + + if (this.options.showPaginationSwitch) { + this.$toolbar.find('button[name="paginationSwitch"]') + .off('click').on('click', $.proxy(this.togglePagination, this)); + } + + if (this.options.showRefresh) { + this.$toolbar.find('button[name="refresh"]') + .off('click').on('click', $.proxy(this.refresh, this)); + } + + if (this.options.showToggle) { + this.$toolbar.find('button[name="toggle"]') + .off('click').on('click', function () { + that.toggleView(); + }); + } + + if (this.options.showColumns) { + $keepOpen = this.$toolbar.find('.keep-open'); + + if (switchableCount <= this.options.minimumCountColumns) { + $keepOpen.find('input').prop('disabled', true); + } + + $keepOpen.find('li').off('click').on('click', function (event) { + event.stopImmediatePropagation(); + }); + $keepOpen.find('input').off('click').on('click', function () { + var $this = $(this); + + that.toggleColumn(getFieldIndex(that.columns, + $(this).data('field')), $this.prop('checked'), false); + that.trigger('column-switch', $(this).data('field'), $this.prop('checked')); + }); + } + + if (this.options.search) { + html = []; + html.push( + ''); + + this.$toolbar.append(html.join('')); + $search = this.$toolbar.find('.search input'); + $search.off('keyup drop').on('keyup drop', function (event) { + clearTimeout(timeoutId); // doesn't matter if it's 0 + timeoutId = setTimeout(function () { + that.onSearch(event); + }, that.options.searchTimeOut); + }); + } + }; + + BootstrapTable.prototype.onSearch = function (event) { + var text = $.trim($(event.currentTarget).val()); + + // trim search input + if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) { + $(event.currentTarget).val(text); + } + + if (text === this.searchText) { + return; + } + this.searchText = text; + + this.options.pageNumber = 1; + this.initSearch(); + this.updatePagination(); + this.trigger('search', text); + }; + + BootstrapTable.prototype.initSearch = function () { + var that = this; + + if (this.options.sidePagination !== 'server') { + var s = this.searchText && this.searchText.toLowerCase(); + var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns; + + // Check filter + this.data = f ? $.grep(this.options.data, function (item, i) { + for (var key in f) { + if (item[key] !== f[key]) { + return false; + } + } + return true; + }) : this.options.data; + + this.data = s ? $.grep(this.data, function (item, i) { + for (var key in item) { + key = $.isNumeric(key) ? parseInt(key, 10) : key; + var value = item[key], + column = that.columns[getFieldIndex(that.columns, key)], + j = $.inArray(key, that.header.fields); + + // Fix #142: search use formated data + if (column && column.searchFormatter) { + value = calculateObjectValue(column, + that.header.formatters[j], [value, item, i], value); + } + + var index = $.inArray(key, that.header.fields); + if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) { + if (that.options.strictSearch) { + if ((value + '').toLowerCase() === s) { + return true; + } + } else { + if ((value + '').toLowerCase().indexOf(s) !== -1) { + return true; + } + } + } + } + return false; + }) : this.data; + } + }; + + BootstrapTable.prototype.initPagination = function () { + if (!this.options.pagination) { + this.$pagination.hide(); + return; + } else { + this.$pagination.show(); + } + + var that = this, + html = [], + $allSelected = false, + i, from, to, + $pageList, + $first, $pre, + $next, $last, + $number, + data = this.getData(); + + if (this.options.sidePagination !== 'server') { + this.options.totalRows = data.length; + } + + this.totalPages = 0; + if (this.options.totalRows) { + if (this.options.pageSize === this.options.formatAllRows()) { + this.options.pageSize = this.options.totalRows; + $allSelected = true; + } else if (this.options.pageSize === this.options.totalRows) { + // Fix #667 Table with pagination, + // multiple pages and a search that matches to one page throws exception + var pageLst = typeof this.options.pageList === 'string' ? + this.options.pageList.replace('[', '').replace(']', '') + .replace(/ /g, '').toLowerCase().split(',') : this.options.pageList; + if (pageLst.indexOf(this.options.formatAllRows().toLowerCase()) > -1) { + $allSelected = true; + } + } + + this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1; + + this.options.totalPages = this.totalPages; + } + if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) { + this.options.pageNumber = this.totalPages; + } + + this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1; + this.pageTo = this.options.pageNumber * this.options.pageSize; + if (this.pageTo > this.options.totalRows) { + this.pageTo = this.options.totalRows; + } + + html.push( + '
', + '', + this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows), + ''); + + html.push(''); + + var pageNumber = [ + sprintf('', + this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ? + 'dropdown' : 'dropup'), + '', + ''); + + html.push(this.options.formatRecordsPerPage(pageNumber.join(''))); + html.push(''); + + html.push('
', + ''); + + this.$pagination.html(html.join('')); + + $pageList = this.$pagination.find('.page-list a'); + $first = this.$pagination.find('.page-first'); + $pre = this.$pagination.find('.page-pre'); + $next = this.$pagination.find('.page-next'); + $last = this.$pagination.find('.page-last'); + $number = this.$pagination.find('.page-number'); + + if (this.options.pageNumber <= 1) { + $first.addClass('disabled'); + $pre.addClass('disabled'); + } + if (this.options.pageNumber >= this.totalPages) { + $next.addClass('disabled'); + $last.addClass('disabled'); + } + if (this.options.smartDisplay) { + if (this.totalPages <= 1) { + this.$pagination.find('div.pagination').hide(); + } + if (pageList.length < 2 || this.options.totalRows <= pageList[0]) { + this.$pagination.find('span.page-list').hide(); + } + + // when data is empty, hide the pagination + this.$pagination[this.getData().length ? 'show' : 'hide'](); + } + if ($allSelected) { + this.options.pageSize = this.options.formatAllRows(); + } + $pageList.off('click').on('click', $.proxy(this.onPageListChange, this)); + $first.off('click').on('click', $.proxy(this.onPageFirst, this)); + $pre.off('click').on('click', $.proxy(this.onPagePre, this)); + $next.off('click').on('click', $.proxy(this.onPageNext, this)); + $last.off('click').on('click', $.proxy(this.onPageLast, this)); + $number.off('click').on('click', $.proxy(this.onPageNumber, this)); + }; + + BootstrapTable.prototype.updatePagination = function (event) { + // Fix #171: IE disabled button can be clicked bug. + if (event && $(event.currentTarget).hasClass('disabled')) { + return; + } + + if (!this.options.maintainSelected) { + this.resetRows(); + } + + this.initPagination(); + if (this.options.sidePagination === 'server') { + this.initServer(); + } else { + this.initBody(); + } + + this.trigger('page-change', this.options.pageNumber, this.options.pageSize); + }; + + BootstrapTable.prototype.onPageListChange = function (event) { + var $this = $(event.currentTarget); + + $this.parent().addClass('active').siblings().removeClass('active'); + this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ? + this.options.formatAllRows() : +$this.text(); + this.$toolbar.find('.page-size').text(this.options.pageSize); + + this.updatePagination(event); + }; + + BootstrapTable.prototype.onPageFirst = function (event) { + this.options.pageNumber = 1; + this.updatePagination(event); + }; + + BootstrapTable.prototype.onPagePre = function (event) { + this.options.pageNumber--; + this.updatePagination(event); + }; + + BootstrapTable.prototype.onPageNext = function (event) { + this.options.pageNumber++; + this.updatePagination(event); + }; + + BootstrapTable.prototype.onPageLast = function (event) { + this.options.pageNumber = this.totalPages; + this.updatePagination(event); + }; + + BootstrapTable.prototype.onPageNumber = function (event) { + if (this.options.pageNumber === +$(event.currentTarget).text()) { + return; + } + this.options.pageNumber = +$(event.currentTarget).text(); + this.updatePagination(event); + }; + + BootstrapTable.prototype.initBody = function (fixedScroll) { + var that = this, + html = [], + data = this.getData(); + + this.trigger('pre-body', data); + + this.$body = this.$el.find('>tbody'); + if (!this.$body.length) { + this.$body = $('').appendTo(this.$el); + } + + //Fix #389 Bootstrap-table-flatJSON is not working + + if (!this.options.pagination || this.options.sidePagination === 'server') { + this.pageFrom = 1; + this.pageTo = data.length; + } + + for (var i = this.pageFrom - 1; i < this.pageTo; i++) { + var key, + item = data[i], + style = {}, + csses = [], + data_ = '', + attributes = {}, + htmlAttributes = []; + + style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style); + + if (style && style.css) { + for (key in style.css) { + csses.push(key + ': ' + style.css[key]); + } + } + + attributes = calculateObjectValue(this.options, + this.options.rowAttributes, [item, i], attributes); + + if (attributes) { + for (key in attributes) { + htmlAttributes.push(sprintf('%s="%s"', key, escapeHTML(attributes[key]))); + } + } + + if (item._data && !$.isEmptyObject(item._data)) { + $.each(item._data, function (k, v) { + // ignore data-index + if (k === 'index') { + return; + } + data_ += sprintf(' data-%s="%s"', k, v); + }); + } + + html.push('' + ); + + if (this.options.cardView) { + html.push(sprintf('', this.header.fields.length)); + } + + if (!this.options.cardView && this.options.detailView) { + html.push('', + '', + sprintf('', this.options.iconsPrefix, this.options.icons.detailOpen), + '', + ''); + } + + $.each(this.header.fields, function (j, field) { + var text = '', + value = getItemField(item, field), + type = '', + cellStyle = {}, + id_ = '', + class_ = that.header.classes[j], + data_ = '', + rowspan_ = '', + title_ = '', + column = that.columns[getFieldIndex(that.columns, field)]; + + if (!column.visible) { + return; + } + + style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; ')); + + value = calculateObjectValue(column, + that.header.formatters[j], [value, item, i], value); + + // handle td's id and class + if (item['_' + field + '_id']) { + id_ = sprintf(' id="%s"', item['_' + field + '_id']); + } + if (item['_' + field + '_class']) { + class_ = sprintf(' class="%s"', item['_' + field + '_class']); + } + if (item['_' + field + '_rowspan']) { + rowspan_ = sprintf(' rowspan="%s"', item['_' + field + '_rowspan']); + } + if (item['_' + field + '_title']) { + title_ = sprintf(' title="%s"', item['_' + field + '_title']); + } + cellStyle = calculateObjectValue(that.header, + that.header.cellStyles[j], [value, item, i], cellStyle); + if (cellStyle.classes) { + class_ = sprintf(' class="%s"', cellStyle.classes); + } + if (cellStyle.css) { + var csses_ = []; + for (var key in cellStyle.css) { + csses_.push(key + ': ' + cellStyle.css[key]); + } + style = sprintf('style="%s"', csses_.concat(that.header.styles[j]).join('; ')); + } + + if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) { + $.each(item['_' + field + '_data'], function (k, v) { + // ignore data-index + if (k === 'index') { + return; + } + data_ += sprintf(' data-%s="%s"', k, v); + }); + } + + if (column.checkbox || column.radio) { + type = column.checkbox ? 'checkbox' : type; + type = column.radio ? 'radio' : type; + + text = [that.options.cardView ? + '
' : '', + '', + that.header.formatters[j] && typeof value === 'string' ? value : '', + that.options.cardView ? '
' : '' + ].join(''); + + item[that.header.stateField] = value === true || (value && value.checked); + } else { + value = typeof value === 'undefined' || value === null ? + that.options.undefinedText : value; + + text = that.options.cardView ? ['
', + that.options.showHeader ? sprintf('%s', style, + getPropertyFromOther(that.columns, 'field', 'title', field)) : '', + sprintf('%s', value), + '
' + ].join('') : [sprintf('', id_, class_, style, data_, rowspan_, title_), + value, + '' + ].join(''); + + // Hide empty data on Card view when smartDisplay is set to true. + if (that.options.cardView && that.options.smartDisplay && value === '') { + text = ''; + } + } + + html.push(text); + }); + + if (this.options.cardView) { + html.push(''); + } + + html.push(''); + } + + // show no records + if (!html.length) { + html.push('', + sprintf('%s', + this.$header.find('th').length, this.options.formatNoMatches()), + ''); + } + + this.$body.html(html.join('')); + + if (!fixedScroll) { + this.scrollTo(0); + } + + // click to select by column + this.$body.find('> tr[data-index] > td').off('click dblclick').on('click dblclick', function (e) { + var $td = $(this), + $tr = $td.parent(), + item = that.data[$tr.data('index')], + index = $td[0].cellIndex, + field = that.header.fields[that.options.detailView && !that.options.cardView ? index - 1 : index], + column = that.columns[getFieldIndex(that.columns, field)], + value = getItemField(item, field); + + if ($td.find('.detail-icon').length) { + return; + } + + that.trigger(e.type === 'click' ? 'click-cell' : 'dbl-click-cell', field, value, item, $td); + that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row', item, $tr); + + // if click to select - then trigger the checkbox/radio click + if (e.type === 'click' && that.options.clickToSelect && column.clickToSelect) { + var $selectItem = $tr.find(sprintf('[name="%s"]', that.options.selectItemName)); + if ($selectItem.length) { + $selectItem[0].click(); // #144: .trigger('click') bug + } + } + }); + + this.$body.find('> tr[data-index] > td > .detail-icon').off('click').on('click', function () { + var $this = $(this), + $tr = $this.parent().parent(), + index = $tr.data('index'), + row = data[index]; // Fix #980 Detail view, when searching, returns wrong row + + // remove and update + if ($tr.next().is('tr.detail-view')) { + $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailOpen)); + $tr.next().remove(); + that.trigger('collapse-row', index, row); + } else { + $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailClose)); + $tr.after(sprintf('%s', + $tr.find('td').length, calculateObjectValue(that.options, + that.options.detailFormatter, [index, row], ''))); + that.trigger('expand-row', index, row, $tr.next().find('td')); + } + that.resetView(); + }); + + this.$selectItem = this.$body.find(sprintf('[name="%s"]', this.options.selectItemName)); + this.$selectItem.off('click').on('click', function (event) { + event.stopImmediatePropagation(); + + var $this = $(this), + checked = $this.prop('checked'), + row = that.data[$this.data('index')]; + + if (that.options.maintainSelected && $(this).is(':radio')) { + $.each(that.options.data, function (i, row) { + row[that.header.stateField] = false; + }); + } + + row[that.header.stateField] = checked; + + if (that.options.singleSelect) { + that.$selectItem.not(this).each(function () { + that.data[$(this).data('index')][that.header.stateField] = false; + }); + that.$selectItem.filter(':checked').not(this).prop('checked', false); + } + + that.updateSelected(); + that.trigger(checked ? 'check' : 'uncheck', row, $this); + }); + + $.each(this.header.events, function (i, events) { + if (!events) { + return; + } + // fix bug, if events is defined with namespace + if (typeof events === 'string') { + events = calculateObjectValue(null, events); + } + + var field = that.header.fields[i], + fieldIndex = $.inArray(field, that.getVisibleFields()); + + if (that.options.detailView && !that.options.cardView) { + fieldIndex += 1; + } + + for (var key in events) { + that.$body.find('>tr').each(function () { + var $tr = $(this), + $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(fieldIndex), + index = key.indexOf(' '), + name = key.substring(0, index), + el = key.substring(index + 1), + func = events[key]; + + $td.find(el).off(name).on(name, function (e) { + var index = $tr.data('index'), + row = that.data[index], + value = row[field]; + + func.apply(this, [e, value, row, index]); + }); + }); + } + }); + + this.updateSelected(); + this.resetView(); + + this.trigger('post-body'); + }; + + BootstrapTable.prototype.initServer = function (silent, query) { + var that = this, + data = {}, + params = { + pageSize: this.options.pageSize === this.options.formatAllRows() ? + this.options.totalRows : this.options.pageSize, + pageNumber: this.options.pageNumber, + searchText: this.searchText, + sortName: this.options.sortName, + sortOrder: this.options.sortOrder + }, + request; + + if (!this.options.url && !this.options.ajax) { + return; + } + + if (this.options.queryParamsType === 'limit') { + params = { + search: params.searchText, + sort: params.sortName, + order: params.sortOrder + }; + if (this.options.pagination) { + params.limit = this.options.pageSize === this.options.formatAllRows() ? + this.options.totalRows : this.options.pageSize; + params.offset = this.options.pageSize === this.options.formatAllRows() ? + 0 : this.options.pageSize * (this.options.pageNumber - 1); + } + } + + if (!($.isEmptyObject(this.filterColumnsPartial))) { + params['filter'] = JSON.stringify(this.filterColumnsPartial, null); + } + + data = calculateObjectValue(this.options, this.options.queryParams, [params], data); + + $.extend(data, query || {}); + + // false to stop request + if (data === false) { + return; + } + + if (!silent) { + this.$tableLoading.show(); + } + request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), { + type: this.options.method, + url: this.options.url, + data: this.options.contentType === 'application/json' && this.options.method === 'post' ? + JSON.stringify(data) : data, + cache: this.options.cache, + contentType: this.options.contentType, + dataType: this.options.dataType, + success: function (res) { + res = calculateObjectValue(that.options, that.options.responseHandler, [res], res); + + that.load(res); + that.trigger('load-success', res); + }, + error: function (res) { + that.trigger('load-error', res.status, res); + }, + complete: function () { + if (!silent) { + that.$tableLoading.hide(); + } + } + }); + + if (this.options.ajax) { + calculateObjectValue(this, this.options.ajax, [request], null); + } else { + $.ajax(request); + } + }; + + BootstrapTable.prototype.initSearchText = function () { + if (this.options.search) { + if (this.options.searchText !== '') { + var $search = this.$toolbar.find('.search input'); + $search.val(this.options.searchText); + this.onSearch({currentTarget: $search}); + } + } + }; + + BootstrapTable.prototype.getCaret = function () { + var that = this; + + $.each(this.$header.find('th'), function (i, th) { + $(th).find('.sortable').removeClass('desc asc').addClass($(th).data('field') === that.options.sortName ? that.options.sortOrder : 'both'); + }); + }; + + BootstrapTable.prototype.updateSelected = function () { + var checkAll = this.$selectItem.filter(':enabled').length && + this.$selectItem.filter(':enabled').length === + this.$selectItem.filter(':enabled').filter(':checked').length; + + this.$selectAll.add(this.$selectAll_).prop('checked', checkAll); + + this.$selectItem.each(function () { + $(this).closest('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected'); + }); + }; + + BootstrapTable.prototype.updateRows = function () { + var that = this; + + this.$selectItem.each(function () { + that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked'); + }); + }; + + BootstrapTable.prototype.resetRows = function () { + var that = this; + + $.each(this.data, function (i, row) { + that.$selectAll.prop('checked', false); + that.$selectItem.prop('checked', false); + if (that.header.stateField) { + row[that.header.stateField] = false; + } + }); + }; + + BootstrapTable.prototype.trigger = function (name) { + var args = Array.prototype.slice.call(arguments, 1); + + name += '.bs.table'; + this.options[BootstrapTable.EVENTS[name]].apply(this.options, args); + this.$el.trigger($.Event(name), args); + + this.options.onAll(name, args); + this.$el.trigger($.Event('all.bs.table'), [name, args]); + }; + + BootstrapTable.prototype.resetHeader = function () { + // fix #61: the hidden table reset header bug. + // fix bug: get $el.css('width') error sometime (height = 500) + clearTimeout(this.timeoutId_); + this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0); + }; + + BootstrapTable.prototype.fitHeader = function () { + var that = this, + fixedBody, + scrollWidth, + focused, + focusedTemp; + + if (that.$el.is(':hidden')) { + that.timeoutId_ = setTimeout($.proxy(that.fitHeader, that), 100); + return; + } + fixedBody = this.$tableBody.get(0); + + scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth && + fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.outerHeight() ? + getScrollBarWidth() : 0; + + this.$el.css('margin-top', -this.$header.outerHeight()); + + focused = $(':focus'); + if (focused.length > 0) { + var $th = focused.parents('th'); + if ($th.length > 0) { + var dataField = $th.attr('data-field'); + if (dataField !== undefined) { + var $headerTh = this.$header.find("[data-field='" + dataField + "']"); + if ($headerTh.length > 0) { + $headerTh.find(":input").addClass("focus-temp"); + } + } + } + } + + this.$header_ = this.$header.clone(true, true); + this.$selectAll_ = this.$header_.find('[name="btSelectAll"]'); + this.$tableHeader.css({ + 'margin-right': scrollWidth + }).find('table').css('width', this.$el.outerWidth()) + .html('').attr('class', this.$el.attr('class')) + .append(this.$header_); + + + focusedTemp = $('.focus-temp:visible:eq(0)'); + if (focusedTemp.length > 0) { + focusedTemp.focus(); + this.$header.find('.focus-temp').removeClass('focus-temp'); + } + + // fix bug: $.data() is not working as expected after $.append() + this.$header.find('th[data-field]').each(function (i) { + that.$header_.find(sprintf('th[data-field="%s"]', $(this).data('field'))).data($(this).data()); + }); + + var visibleFields = this.getVisibleFields(); + + this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) { + var $this = $(this), + index = i; + + if (that.options.detailView && !that.options.cardView) { + if (i === 0) { + that.$header_.find('th.detail').find('.fht-cell').width($this.innerWidth()); + } + index = i - 1; + } + + that.$header_.find(sprintf('th[data-field="%s"]', visibleFields[index])) + .find('.fht-cell').width($this.innerWidth()); + }); + // horizontal scroll event + // TODO: it's probably better improving the layout than binding to scroll event + this.$tableBody.off('scroll').on('scroll', function () { + that.$tableHeader.scrollLeft($(this).scrollLeft()); + + if (that.options.showFooter && !that.options.cardView) { + that.$tableFooter.scrollLeft($(this).scrollLeft()); + } + }); + that.trigger('post-header'); + }; + + BootstrapTable.prototype.resetFooter = function () { + var that = this, + data = that.getData(), + html = []; + + if (!this.options.showFooter || this.options.cardView) { //do nothing + return; + } + + if (!this.options.cardView && this.options.detailView) { + html.push('
 
'); + } + + $.each(this.columns, function (i, column) { + var falign = '', // footer align style + style = '', + class_ = sprintf(' class="%s"', column['class']); + + if (!column.visible) { + return; + } + + if (that.options.cardView && (!column.cardVisible)) { + return; + } + + falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align); + style = sprintf('vertical-align: %s; ', column.valign); + + html.push(''); + html.push('
'); + + html.push(calculateObjectValue(column, column.footerFormatter, [data], ' ') || ' '); + + html.push('
'); + html.push('
'); + html.push('
'); + html.push(''); + }); + + this.$tableFooter.find('tr').html(html.join('')); + clearTimeout(this.timeoutFooter_); + this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), + this.$el.is(':hidden') ? 100 : 0); + }; + + BootstrapTable.prototype.fitFooter = function () { + var that = this, + $footerTd, + elWidth, + scrollWidth; + + clearTimeout(this.timeoutFooter_); + if (this.$el.is(':hidden')) { + this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100); + return; + } + + elWidth = this.$el.css('width'); + scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0; + + this.$tableFooter.css({ + 'margin-right': scrollWidth + }).find('table').css('width', elWidth) + .attr('class', this.$el.attr('class')); + + $footerTd = this.$tableFooter.find('td'); + + this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) { + var $this = $(this); + + $footerTd.eq(i).find('.fht-cell').width($this.innerWidth()); + }); + }; + + BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) { + if (index === -1) { + return; + } + this.columns[index].visible = checked; + this.initHeader(); + this.initSearch(); + this.initPagination(); + this.initBody(); + + if (this.options.showColumns) { + var $items = this.$toolbar.find('.keep-open input').prop('disabled', false); + + if (needUpdate) { + $items.filter(sprintf('[value="%s"]', index)).prop('checked', checked); + } + + if ($items.filter(':checked').length <= this.options.minimumCountColumns) { + $items.filter(':checked').prop('disabled', true); + } + } + }; + + BootstrapTable.prototype.toggleRow = function (index, uniqueId, visible) { + if (index === -1) { + return; + } + + this.$body.find(typeof index !== 'undefined' ? + sprintf('tr[data-index="%s"]', index) : + sprintf('tr[data-uniqueid="%s"]', uniqueId)) + [visible ? 'show' : 'hide'](); + }; + + BootstrapTable.prototype.getVisibleFields = function () { + var that = this, + visibleFields = []; + + $.each(this.header.fields, function (j, field) { + var column = that.columns[getFieldIndex(that.columns, field)]; + + if (!column.visible) { + return; + } + visibleFields.push(field); + }); + return visibleFields; + }; + + // PUBLIC FUNCTION DEFINITION + // ======================= + + BootstrapTable.prototype.resetView = function (params) { + var padding = 0; + + if (params && params.height) { + this.options.height = params.height; + } + + this.$selectAll.prop('checked', this.$selectItem.length > 0 && + this.$selectItem.length === this.$selectItem.filter(':checked').length); + + if (this.options.height) { + var toolbarHeight = getRealHeight(this.$toolbar), + paginationHeight = getRealHeight(this.$pagination), + height = this.options.height - toolbarHeight - paginationHeight; + + this.$tableContainer.css('height', height + 'px'); + } + + if (this.options.cardView) { + // remove the element css + this.$el.css('margin-top', '0'); + this.$tableContainer.css('padding-bottom', '0'); + return; + } + + if (this.options.showHeader && this.options.height) { + this.$tableHeader.show(); + this.resetHeader(); + padding += this.$header.outerHeight(); + } else { + this.$tableHeader.hide(); + this.trigger('post-header'); + } + + if (this.options.showFooter) { + this.resetFooter(); + if (this.options.height) { + padding += this.$tableFooter.outerHeight() + 1; + } + } + + // Assign the correct sortable arrow + this.getCaret(); + this.$tableContainer.css('padding-bottom', padding + 'px'); + this.trigger('reset-view'); + }; + + BootstrapTable.prototype.getData = function (useCurrentPage) { + return (this.searchText || !$.isEmptyObject(this.filterColumns) || !$.isEmptyObject(this.filterColumnsPartial)) ? + (useCurrentPage ? this.data.slice(this.pageFrom - 1, this.pageTo) : this.data) : + (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo) : this.options.data); + }; + + BootstrapTable.prototype.load = function (data) { + var fixedScroll = false; + + // #431: support pagination + if (this.options.sidePagination === 'server') { + this.options.totalRows = data.total; + fixedScroll = data.fixedScroll; + data = data[this.options.dataField]; + } else if (!$.isArray(data)) { // support fixedScroll + fixedScroll = data.fixedScroll; + data = data.data; + } + + this.initData(data); + this.initSearch(); + this.initPagination(); + this.initBody(fixedScroll); + }; + + BootstrapTable.prototype.append = function (data) { + this.initData(data, 'append'); + this.initSearch(); + this.initPagination(); + this.initBody(true); + }; + + BootstrapTable.prototype.prepend = function (data) { + this.initData(data, 'prepend'); + this.initSearch(); + this.initPagination(); + this.initBody(true); + }; + + BootstrapTable.prototype.remove = function (params) { + var len = this.options.data.length, + i, row; + + if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) { + return; + } + + for (i = len - 1; i >= 0; i--) { + row = this.options.data[i]; + + if (!row.hasOwnProperty(params.field)) { + continue; + } + if ($.inArray(row[params.field], params.values) !== -1) { + this.options.data.splice(i, 1); + } + } + + if (len === this.options.data.length) { + return; + } + + this.initSearch(); + this.initPagination(); + this.initBody(true); + }; + + BootstrapTable.prototype.removeAll = function () { + if (this.options.data.length > 0) { + this.options.data.splice(0, this.options.data.length); + this.initSearch(); + this.initPagination(); + this.initBody(true); + } + }; + + BootstrapTable.prototype.getRowByUniqueId = function (id) { + var uniqueId = this.options.uniqueId, + len = this.options.data.length, + dataRow = null, + i, row; + + for (i = len - 1; i >= 0; i--) { + row = this.options.data[i]; + + if (!row.hasOwnProperty(uniqueId)) { + continue; + } + + if (typeof row[uniqueId] === 'string') { + id = id.toString(); + } else if (typeof row[uniqueId] === 'number') { + if ((Number(row[uniqueId]) === row[uniqueId]) && (row[uniqueId] % 1 === 0)) { + id = parseInt(id); + } else if ((row[uniqueId] === Number(row[uniqueId])) && (row[uniqueId] !== 0)) { + id = parseFloat(id); + } + } + + if (row[uniqueId] === id) { + dataRow = row; + break; + } + } + + return dataRow; + }; + + BootstrapTable.prototype.removeByUniqueId = function (id) { + var len = this.options.data.length, + row = this.getRowByUniqueId(id); + + if (row) { + this.options.data.splice(this.options.data.indexOf(row), 1); + } + + if (len === this.options.data.length) { + return; + } + + this.initSearch(); + this.initPagination(); + this.initBody(true); + }; + + BootstrapTable.prototype.insertRow = function (params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) { + return; + } + this.data.splice(params.index, 0, params.row); + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.updateRow = function (params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) { + return; + } + $.extend(this.data[params.index], params.row); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.showRow = function (params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('uniqueId')) { + return; + } + this.toggleRow(params.index, params.uniqueId, true); + }; + + BootstrapTable.prototype.hideRow = function (params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('uniqueId')) { + return; + } + this.toggleRow(params.index, params.uniqueId, false); + }; + + BootstrapTable.prototype.getRowsHidden = function (show) { + var rows = $(this.$body[0]).children().filter(':hidden'), + i = 0; + if (show) { + for (; i < rows.length; i++) { + $(rows[i]).show(); + } + } + return rows; + }; + + BootstrapTable.prototype.mergeCells = function (options) { + var row = options.index, + col = $.inArray(options.field, this.getVisibleFields()), + rowspan = options.rowspan || 1, + colspan = options.colspan || 1, + i, j, + $tr = this.$body.find('>tr'), + $td; + + if (this.options.detailView && !this.options.cardView) { + col += 1; + } + + $td = $tr.eq(row).find('>td').eq(col); + + if (row < 0 || col < 0 || row >= this.data.length) { + return; + } + + for (i = row; i < row + rowspan; i++) { + for (j = col; j < col + colspan; j++) { + $tr.eq(i).find('>td').eq(j).hide(); + } + } + + $td.attr('rowspan', rowspan).attr('colspan', colspan).show(); + }; + + BootstrapTable.prototype.updateCell = function (params) { + if (!params.hasOwnProperty('index') || + !params.hasOwnProperty('field') || + !params.hasOwnProperty('value')) { + return; + } + this.data[params.index][params.field] = params.value; + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.getOptions = function () { + return this.options; + }; + + BootstrapTable.prototype.getSelections = function () { + var that = this; + + return $.grep(this.data, function (row) { + return row[that.header.stateField]; + }); + }; + + BootstrapTable.prototype.getAllSelections = function () { + var that = this; + + return $.grep(this.options.data, function (row) { + return row[that.header.stateField]; + }); + }; + + BootstrapTable.prototype.checkAll = function () { + this.checkAll_(true); + }; + + BootstrapTable.prototype.uncheckAll = function () { + this.checkAll_(false); + }; + + BootstrapTable.prototype.checkAll_ = function (checked) { + var rows; + if (!checked) { + rows = this.getSelections(); + } + this.$selectAll.add(this.$selectAll_).prop('checked', checked); + this.$selectItem.filter(':enabled').prop('checked', checked); + this.updateRows(); + if (checked) { + rows = this.getSelections(); + } + this.trigger(checked ? 'check-all' : 'uncheck-all', rows); + }; + + BootstrapTable.prototype.check = function (index) { + this.check_(true, index); + }; + + BootstrapTable.prototype.uncheck = function (index) { + this.check_(false, index); + }; + + BootstrapTable.prototype.check_ = function (checked, index) { + this.$selectItem.filter(sprintf('[data-index="%s"]', index)).prop('checked', checked); + this.data[index][this.header.stateField] = checked; + this.updateSelected(); + this.trigger(checked ? 'check' : 'uncheck', this.data[index]); + }; + + BootstrapTable.prototype.checkBy = function (obj) { + this.checkBy_(true, obj); + }; + + BootstrapTable.prototype.uncheckBy = function (obj) { + this.checkBy_(false, obj); + }; + + BootstrapTable.prototype.checkBy_ = function (checked, obj) { + if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) { + return; + } + + var that = this, + rows = []; + $.each(this.options.data, function (index, row) { + if (!row.hasOwnProperty(obj.field)) { + return false; + } + if ($.inArray(row[obj.field], obj.values) !== -1) { + that.$selectItem.filter(':enabled') + .filter(sprintf('[data-index="%s"]', index)).prop('checked', checked); + row[that.header.stateField] = checked; + rows.push(row); + that.trigger(checked ? 'check' : 'uncheck', row); + } + }); + this.updateSelected(); + this.trigger(checked ? 'check-some' : 'uncheck-some', rows); + }; + + BootstrapTable.prototype.destroy = function () { + this.$el.insertBefore(this.$container); + $(this.options.toolbar).insertBefore(this.$el); + this.$container.next().remove(); + this.$container.remove(); + this.$el.html(this.$el_.html()) + .css('margin-top', '0') + .attr('class', this.$el_.attr('class') || ''); // reset the class + }; + + BootstrapTable.prototype.showLoading = function () { + this.$tableLoading.show(); + }; + + BootstrapTable.prototype.hideLoading = function () { + this.$tableLoading.hide(); + }; + + BootstrapTable.prototype.togglePagination = function () { + this.options.pagination = !this.options.pagination; + var button = this.$toolbar.find('button[name="paginationSwitch"] i'); + if (this.options.pagination) { + button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchDown); + } else { + button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchUp); + } + this.updatePagination(); + }; + + BootstrapTable.prototype.refresh = function (params) { + if (params && params.url) { + this.options.url = params.url; + this.options.pageNumber = 1; + } + this.initServer(params && params.silent, params && params.query); + }; + + BootstrapTable.prototype.resetWidth = function () { + if (this.options.showHeader && this.options.height) { + this.fitHeader(); + } + if (this.options.showFooter) { + this.fitFooter(); + } + }; + + BootstrapTable.prototype.showColumn = function (field) { + this.toggleColumn(getFieldIndex(this.columns, field), true, true); + }; + + BootstrapTable.prototype.hideColumn = function (field) { + this.toggleColumn(getFieldIndex(this.columns, field), false, true); + }; + + BootstrapTable.prototype.getHiddenColumns = function () { + return $.grep(this.columns, function (column) { + return !column.visible; + }); + }; + + BootstrapTable.prototype.filterBy = function (columns) { + this.filterColumns = $.isEmptyObject(columns) ? {} : columns; + this.options.pageNumber = 1; + this.initSearch(); + this.updatePagination(); + }; + + BootstrapTable.prototype.scrollTo = function (value) { + if (typeof value === 'string') { + value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0; + } + if (typeof value === 'number') { + this.$tableBody.scrollTop(value); + } + if (typeof value === 'undefined') { + return this.$tableBody.scrollTop(); + } + }; + + BootstrapTable.prototype.getScrollPosition = function () { + return this.scrollTo(); + }; + + BootstrapTable.prototype.selectPage = function (page) { + if (page > 0 && page <= this.options.totalPages) { + this.options.pageNumber = page; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.prevPage = function () { + if (this.options.pageNumber > 1) { + this.options.pageNumber--; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.nextPage = function () { + if (this.options.pageNumber < this.options.totalPages) { + this.options.pageNumber++; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.toggleView = function () { + this.options.cardView = !this.options.cardView; + this.initHeader(); + // Fixed remove toolbar when click cardView button. + //that.initToolbar(); + this.initBody(); + this.trigger('toggle', this.options.cardView); + }; + + BootstrapTable.prototype.refreshOptions = function (options) { + //If the objects are equivalent then avoid the call of destroy / init methods + if (compareObjects(this.options, options, false)) { + return; + } + this.options = $.extend(this.options, options); + this.trigger('refresh-options', this.options); + this.destroy(); + this.init(); + }; + + BootstrapTable.prototype.resetSearch = function (text) { + var $search = this.$toolbar.find('.search input'); + $search.val(text || ''); + this.onSearch({currentTarget: $search}); + }; + + BootstrapTable.prototype.expandRow_ = function (expand, index) { + var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', index)); + if ($tr.next().is('tr.detail-view') === (expand ? false : true)) { + $tr.find('> td > .detail-icon').click(); + } + }; + + BootstrapTable.prototype.expandRow = function (index) { + this.expandRow_(true, index); + }; + + BootstrapTable.prototype.collapseRow = function (index) { + this.expandRow_(false, index); + }; + + BootstrapTable.prototype.expandAllRows = function (isSubTable) { + if (isSubTable) { + var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', 0)), + that = this, + detailIcon = null, + executeInterval = false, + idInterval = -1; + + if (!$tr.next().is('tr.detail-view')) { + $tr.find('> td > .detail-icon').click(); + executeInterval = true; + } else if (!$tr.next().next().is('tr.detail-view')) { + $tr.next().find(".detail-icon").click(); + executeInterval = true; + } + + if (executeInterval) { + try { + idInterval = setInterval(function () { + detailIcon = that.$body.find("tr.detail-view").last().find(".detail-icon"); + if (detailIcon.length > 0) { + detailIcon.click(); + } else { + clearInterval(idInterval); + } + }, 1); + } catch (ex) { + clearInterval(idInterval); + } + } + } else { + var trs = this.$body.children(); + for (var i = 0; i < trs.length; i++) { + this.expandRow_(true, $(trs[i]).data("index")); + } + } + }; + + BootstrapTable.prototype.collapseAllRows = function (isSubTable) { + if (isSubTable) { + this.expandRow_(false, 0); + } else { + var trs = this.$body.children(); + for (var i = 0; i < trs.length; i++) { + this.expandRow_(false, $(trs[i]).data("index")); + } + } + }; + + // BOOTSTRAP TABLE PLUGIN DEFINITION + // ======================= + + var allowedMethods = [ + 'getOptions', + 'getSelections', 'getAllSelections', 'getData', + 'load', 'append', 'prepend', 'remove', 'removeAll', + 'insertRow', 'updateRow', 'updateCell', 'removeByUniqueId', + 'getRowByUniqueId', 'showRow', 'hideRow', 'getRowsHidden', + 'mergeCells', + 'checkAll', 'uncheckAll', + 'check', 'uncheck', + 'checkBy', 'uncheckBy', + 'refresh', + 'resetView', + 'resetWidth', + 'destroy', + 'showLoading', 'hideLoading', + 'showColumn', 'hideColumn', 'getHiddenColumns', + 'filterBy', + 'scrollTo', + 'getScrollPosition', + 'selectPage', 'prevPage', 'nextPage', + 'togglePagination', + 'toggleView', + 'refreshOptions', + 'resetSearch', + 'expandRow', 'collapseRow', 'expandAllRows', 'collapseAllRows' + ]; + + $.fn.bootstrapTable = function (option) { + var value, + args = Array.prototype.slice.call(arguments, 1); + + this.each(function () { + var $this = $(this), + data = $this.data('bootstrap.table'), + options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(), + typeof option === 'object' && option); + + if (typeof option === 'string') { + if ($.inArray(option, allowedMethods) < 0) { + throw new Error("Unknown method: " + option); + } + + if (!data) { + return; + } + + value = data[option].apply(data, args); + + if (option === 'destroy') { + $this.removeData('bootstrap.table'); + } + } + + if (!data) { + $this.data('bootstrap.table', (data = new BootstrapTable(this, options))); + } + }); + + return typeof value === 'undefined' ? this : value; + }; + + $.fn.bootstrapTable.Constructor = BootstrapTable; + $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS; + $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS; + $.fn.bootstrapTable.locales = BootstrapTable.LOCALES; + $.fn.bootstrapTable.methods = allowedMethods; + $.fn.bootstrapTable.utils = { + sprintf: sprintf, + getFieldIndex: getFieldIndex, + compareObjects: compareObjects, + calculateObjectValue: calculateObjectValue + }; + + // BOOTSTRAP TABLE INIT + // ======================= + + $(function () { + $('[data-toggle="table"]').bootstrapTable(); + }); + +}(jQuery); diff --git a/public/assets/js/extensions/accent-neutralise/README.md b/public/assets/js/extensions/accent-neutralise/README.md new file mode 100755 index 0000000000..c2f3d09500 --- /dev/null +++ b/public/assets/js/extensions/accent-neutralise/README.md @@ -0,0 +1,17 @@ +# Table Accent Neutralise + +Use Plugin: [bootstrap-table-accent-neutralise](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/accent-neutralise) + +## Usage + +```html + +``` + +## Options + +### searchAccentNeutralise + +* type: Boolean +* description: Set to true if you want to use accent neutralise feature. +* default: `false` diff --git a/public/assets/js/extensions/accent-neutralise/bootstrap-table-accent-neutralise.js b/public/assets/js/extensions/accent-neutralise/bootstrap-table-accent-neutralise.js new file mode 100755 index 0000000000..dc7b4f08fc --- /dev/null +++ b/public/assets/js/extensions/accent-neutralise/bootstrap-table-accent-neutralise.js @@ -0,0 +1,182 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + */ + +!function ($) { + + 'use strict'; + + var diacriticsMap = {}; + var defaultAccentsDiacritics = [ + {'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'}, + {'base':'AA','letters':'\uA732'}, + {'base':'AE','letters':'\u00C6\u01FC\u01E2'}, + {'base':'AO','letters':'\uA734'}, + {'base':'AU','letters':'\uA736'}, + {'base':'AV','letters':'\uA738\uA73A'}, + {'base':'AY','letters':'\uA73C'}, + {'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'}, + {'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'}, + {'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'}, + {'base':'DZ','letters':'\u01F1\u01C4'}, + {'base':'Dz','letters':'\u01F2\u01C5'}, + {'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'}, + {'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'}, + {'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'}, + {'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'}, + {'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'}, + {'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'}, + {'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'}, + {'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'}, + {'base':'LJ','letters':'\u01C7'}, + {'base':'Lj','letters':'\u01C8'}, + {'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'}, + {'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'}, + {'base':'NJ','letters':'\u01CA'}, + {'base':'Nj','letters':'\u01CB'}, + {'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'}, + {'base':'OI','letters':'\u01A2'}, + {'base':'OO','letters':'\uA74E'}, + {'base':'OU','letters':'\u0222'}, + {'base':'OE','letters':'\u008C\u0152'}, + {'base':'oe','letters':'\u009C\u0153'}, + {'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'}, + {'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'}, + {'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'}, + {'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'}, + {'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'}, + {'base':'TZ','letters':'\uA728'}, + {'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'}, + {'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'}, + {'base':'VY','letters':'\uA760'}, + {'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'}, + {'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'}, + {'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'}, + {'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'}, + {'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'}, + {'base':'aa','letters':'\uA733'}, + {'base':'ae','letters':'\u00E6\u01FD\u01E3'}, + {'base':'ao','letters':'\uA735'}, + {'base':'au','letters':'\uA737'}, + {'base':'av','letters':'\uA739\uA73B'}, + {'base':'ay','letters':'\uA73D'}, + {'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'}, + {'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'}, + {'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'}, + {'base':'dz','letters':'\u01F3\u01C6'}, + {'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'}, + {'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'}, + {'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'}, + {'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'}, + {'base':'hv','letters':'\u0195'}, + {'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'}, + {'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'}, + {'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'}, + {'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'}, + {'base':'lj','letters':'\u01C9'}, + {'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'}, + {'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'}, + {'base':'nj','letters':'\u01CC'}, + {'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'}, + {'base':'oi','letters':'\u01A3'}, + {'base':'ou','letters':'\u0223'}, + {'base':'oo','letters':'\uA74F'}, + {'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'}, + {'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'}, + {'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'}, + {'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'}, + {'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'}, + {'base':'tz','letters':'\uA729'}, + {'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'}, + {'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'}, + {'base':'vy','letters':'\uA761'}, + {'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'}, + {'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'}, + {'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'}, + {'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'} + ]; + + var initNeutraliser = function () { + for (var i=0; i < defaultAccentsDiacritics.length; i++){ + var letters = defaultAccentsDiacritics[i].letters; + for (var j=0; j < letters.length ; j++){ + diacriticsMap[letters[j]] = defaultAccentsDiacritics[i].base; + } + } + }; + + var removeDiacritics = function (str) { + return str.replace(/[^\u0000-\u007E]/g, function(a){ + return diacriticsMap[a] || a; + }); + }; + + $.extend($.fn.bootstrapTable.defaults, { + searchAccentNeutralise: false + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.init = function () { + if (this.options.searchAccentNeutralise) { + initNeutraliser(); + } + _init.apply(this, Array.prototype.slice.apply(arguments)); + }; + + BootstrapTable.prototype.initSearch = function () { + var that = this; + + if (this.options.sidePagination !== 'server') { + var s = this.searchText && this.searchText.toLowerCase(); + var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns; + + // Check filter + this.data = f ? $.grep(this.options.data, function (item, i) { + for (var key in f) { + if (item[key] !== f[key]) { + return false; + } + } + return true; + }) : this.options.data; + + this.data = s ? $.grep(this.data, function (item, i) { + for (var key in item) { + key = $.isNumeric(key) ? parseInt(key, 10) : key; + var value = item[key], + column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)], + j = $.inArray(key, that.header.fields); + + if (column && column.searchFormatter) { + value = $.fn.bootstrapTable.utils.calculateObjectValue(column, + that.header.formatters[j], [value, item, i], value); + } + + var index = $.inArray(key, that.header.fields); + if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) { + if (that.options.searchAccentNeutralise) { + value = removeDiacritics(value); + s = removeDiacritics(s); + } + if (that.options.strictSearch) { + if ((value + '').toLowerCase() === s) { + return true; + } + } else { + if ((value + '').toLowerCase().indexOf(s) !== -1) { + return true; + } + } + } + } + return false; + }) : this.data; + } + }; + +}(jQuery); diff --git a/public/assets/js/extensions/angular/bootstrap-table-angular.js b/public/assets/js/extensions/angular/bootstrap-table-angular.js new file mode 100755 index 0000000000..84c4ed330a --- /dev/null +++ b/public/assets/js/extensions/angular/bootstrap-table-angular.js @@ -0,0 +1,105 @@ +// JavaScript source code +(function () { + if (typeof angular === 'undefined') { + return; + } + angular.module('bsTable', []).directive('bsTableControl', function () { + var CONTAINER_SELECTOR = '.bootstrap-table'; + var SCROLLABLE_SELECTOR = '.fixed-table-body'; + var SEARCH_SELECTOR = '.search input'; + var bsTables = {}; + function getBsTable (el) { + var result; + $.each(bsTables, function (id, bsTable) { + if (!bsTable.$el.closest(CONTAINER_SELECTOR).has(el).length) return; + result = bsTable; + return true; + }); + return result; + } + + $(window).resize(function () { + $.each(bsTables, function (id, bsTable) { + bsTable.$el.bootstrapTable('resetView'); + }); + }); + function onScroll () { + var bsTable = this; + var state = bsTable.$s.bsTableControl.state; + bsTable.$s.$applyAsync(function () { + state.scroll = bsTable.$el.bootstrapTable('getScrollPosition'); + }); + } + $(document) + .on('post-header.bs.table', CONTAINER_SELECTOR+' table', function (evt) { // bootstrap-table calls .off('scroll') in initHeader so reattach here + var bsTable = getBsTable(evt.target); + if (!bsTable) return; + bsTable.$el + .closest(CONTAINER_SELECTOR) + .find(SCROLLABLE_SELECTOR) + .on('scroll', onScroll.bind(bsTable)); + }) + .on('sort.bs.table', CONTAINER_SELECTOR+' table', function (evt, sortName, sortOrder) { + var bsTable = getBsTable(evt.target); + if (!bsTable) return; + var state = bsTable.$s.bsTableControl.state; + bsTable.$s.$applyAsync(function () { + state.sortName = sortName; + state.sortOrder = sortOrder; + }); + }) + .on('page-change.bs.table', CONTAINER_SELECTOR+' table', function (evt, pageNumber, pageSize) { + var bsTable = getBsTable(evt.target); + if (!bsTable) return; + var state = bsTable.$s.bsTableControl.state; + bsTable.$s.$applyAsync(function () { + state.pageNumber = pageNumber; + state.pageSize = pageSize; + }); + }) + .on('search.bs.table', CONTAINER_SELECTOR+' table', function (evt, searchText) { + var bsTable = getBsTable(evt.target); + if (!bsTable) return; + var state = bsTable.$s.bsTableControl.state; + bsTable.$s.$applyAsync(function () { + state.searchText = searchText; + }); + }) + .on('focus blur', CONTAINER_SELECTOR+' '+SEARCH_SELECTOR, function (evt) { + var bsTable = getBsTable(evt.target); + if (!bsTable) return; + var state = bsTable.$s.bsTableControl.state; + bsTable.$s.$applyAsync(function () { + state.searchHasFocus = $(evt.target).is(':focus'); + }); + }); + + return { + restrict: 'EA', + scope: {bsTableControl: '='}, + link: function ($s, $el) { + var bsTable = bsTables[$s.$id] = {$s: $s, $el: $el}; + $s.instantiated = false; + $s.$watch('bsTableControl.options', function (options) { + if (!options) options = $s.bsTableControl.options = {}; + var state = $s.bsTableControl.state || {}; + + if ($s.instantiated) $el.bootstrapTable('destroy'); + $el.bootstrapTable(angular.extend(angular.copy(options), state)); + $s.instantiated = true; + + // Update the UI for state that isn't settable via options + if ('scroll' in state) $el.bootstrapTable('scrollTo', state.scroll); + if ('searchHasFocus' in state) $el.closest(CONTAINER_SELECTOR).find(SEARCH_SELECTOR).focus(); // $el gets detached so have to recompute whole chain + }, true); + $s.$watch('bsTableControl.state', function (state) { + if (!state) state = $s.bsTableControl.state = {}; + $el.trigger('directive-updated.bs.table', [state]); + }, true); + $s.$on('$destroy', function () { + delete bsTables[$s.$id]; + }); + } + }; + }) +})(); diff --git a/public/assets/js/extensions/cookie/README.md b/public/assets/js/extensions/cookie/README.md new file mode 100755 index 0000000000..727affa0a6 --- /dev/null +++ b/public/assets/js/extensions/cookie/README.md @@ -0,0 +1,62 @@ +# Table Cookie + +Use Plugin: [bootstrap-table-cookie](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/cookie) + +## Usage + +```html + +``` + +## Options + +### cookie + +* type: Boolean +* description: Set true to save the state of a table (its paging position, ordering state, records per page). +* default: `false` + +### cookieExpire + +* type: String +* description: You must set this property if cookie option is enable to know when will expire the cookie created. Must use this format: 'number{letter}' like '2h', in the letter position + you can use: 's','mi','h','d','m','y', these means: 'seconds', 'minutes', 'hours', 'days', 'months', 'years'. +* default: `2h` + +### cookiePath + +* type: String +* description: you can tell the browser what path the cookie belongs to. By default, the cookie belongs to the current page. +* default: `null` + +### cookieDomain + +* type: String +* description: This is the website domain, with the www. prefix removed. +* default: `null` + +### cookieSecure + +* type: Boolean +* description: This property keeps cookie communication limited to encrypted transmission, directing browsers to use cookies only via secure/encrypted connections. +* default: `null` + +### cookieIdTable + +* type: String +* description: You must set this property if the cookie property is enabled to set an unique cookie with an identifier for each table in your page or project. You must set this property because we need create cookies with an identifier. +* default: `` + +### cookiesEnabled + +* type: Array +* description: Set this array with the table properties (sortOrder, sortName, pageNumber, pageList, columns, searchText, filterControl) that you want to save +* default: `['bs.table.sortOrder', 'bs.table.sortName', 'bs.table.pageNumber', 'bs.table.pageList', 'bs.table.columns', 'bs.table.searchText', 'bs.table.filterControl']` + +## This plugin saves + +* Sort order +* Page number +* Page number from the list +* Visible columns +* Search text \ No newline at end of file diff --git a/public/assets/js/extensions/cookie/bootstrap-table-cookie.js b/public/assets/js/extensions/cookie/bootstrap-table-cookie.js new file mode 100755 index 0000000000..e6f8d5cc4c --- /dev/null +++ b/public/assets/js/extensions/cookie/bootstrap-table-cookie.js @@ -0,0 +1,331 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.2.0 + * + * @update zhixin wen + */ + +(function ($) { + 'use strict'; + + var cookieIds = { + sortOrder: 'bs.table.sortOrder', + sortName: 'bs.table.sortName', + pageNumber: 'bs.table.pageNumber', + pageList: 'bs.table.pageList', + columns: 'bs.table.columns', + searchText: 'bs.table.searchText', + filterControl: 'bs.table.filterControl' + }; + + var getCurrentHeader = function (that) { + var header = that.$header; + if (that.options.height) { + header = that.$tableHeader; + } + + return header; + }; + + var getCurrentSearchControls = function (that) { + var searchControls = 'select, input'; + if (that.options.height) { + searchControls = 'table select, table input'; + } + + return searchControls; + }; + + var cookieEnabled = function () { + return !!(navigator.cookieEnabled); + }; + + var inArrayCookiesEnabled = function (cookieName, cookiesEnabled) { + var index = -1; + + for (var i = 0; i < cookiesEnabled.length; i++) { + if (cookieName.toLowerCase() === cookiesEnabled[i].toLowerCase()) { + index = i; + break; + } + } + + return index; + }; + + var setCookie = function (that, cookieName, cookieValue) { + if ((!that.options.cookie) || (!cookieEnabled()) || (that.options.cookieIdTable === '')) { + return; + } + + if (inArrayCookiesEnabled(cookieName, that.options.cookiesEnabled) === -1) { + return; + } + + cookieName = that.options.cookieIdTable + '.' + cookieName; + if (!cookieName || /^(?:expires|max\-age|path|domain|secure)$/i.test(cookieName)) { + return false; + } + + document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(cookieValue) + calculateExpiration(that.options.cookieExpire) + (that.options.cookieDomain ? '; domain=' + that.options.cookieDomain : '') + (that.options.cookiePath ? '; path=' + that.options.cookiePath : '') + (that.cookieSecure ? '; secure' : ''); + return true; + }; + + var getCookie = function (that, tableName, cookieName) { + if (!cookieName) { + return null; + } + + if (inArrayCookiesEnabled(cookieName, that.options.cookiesEnabled) === -1) { + return null; + } + + cookieName = tableName + '.' + cookieName; + + return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(cookieName).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null; + }; + + var hasCookie = function (cookieName) { + if (!cookieName) { + return false; + } + return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(cookieName).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(document.cookie); + }; + + var deleteCookie = function (tableName, cookieName, sPath, sDomain) { + cookieName = tableName + '.' + cookieName; + if (!hasCookie(cookieName)) { + return false; + } + document.cookie = encodeURIComponent(cookieName) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : ''); + return true; + }; + + var calculateExpiration = function(cookieExpire) { + var time = cookieExpire.replace(/[0-9]*/, ''); //s,mi,h,d,m,y + cookieExpire = cookieExpire.replace(/[A-Za-z]/, ''); //number + + switch (time.toLowerCase()) { + case 's': + cookieExpire = +cookieExpire; + break; + case 'mi': + cookieExpire = cookieExpire * 60; + break; + case 'h': + cookieExpire = cookieExpire * 60 * 60; + break; + case 'd': + cookieExpire = cookieExpire * 24 * 60 * 60; + break; + case 'm': + cookieExpire = cookieExpire * 30 * 24 * 60 * 60; + break; + case 'y': + cookieExpire = cookieExpire * 365 * 30 * 24 * 60 * 60; + break; + default: + cookieExpire = undefined; + break; + } + + return cookieExpire === undefined ? '' : '; max-age=' + cookieExpire; + }; + + $.extend($.fn.bootstrapTable.defaults, { + cookie: false, + cookieExpire: '2h', + cookiePath: null, + cookieDomain: null, + cookieSecure: null, + cookieIdTable: '', + cookiesEnabled: ['bs.table.sortOrder', 'bs.table.sortName', 'bs.table.pageNumber', 'bs.table.pageList', 'bs.table.columns', 'bs.table.searchText', 'bs.table.filterControl'], + //internal variable + filterControls: [], + filterControlValuesLoaded: false + }); + + $.fn.bootstrapTable.methods.push('deleteCookie'); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initTable = BootstrapTable.prototype.initTable, + _onSort = BootstrapTable.prototype.onSort, + _onPageNumber = BootstrapTable.prototype.onPageNumber, + _onPageListChange = BootstrapTable.prototype.onPageListChange, + _onPageFirst = BootstrapTable.prototype.onPageFirst, + _onPagePre = BootstrapTable.prototype.onPagePre, + _onPageNext = BootstrapTable.prototype.onPageNext, + _onPageLast = BootstrapTable.prototype.onPageLast, + _toggleColumn = BootstrapTable.prototype.toggleColumn, + _selectPage = BootstrapTable.prototype.selectPage, + _onSearch = BootstrapTable.prototype.onSearch; + + BootstrapTable.prototype.init = function () { + var timeoutId = 0; + this.options.filterControls = []; + this.options.filterControlValuesLoaded = false; + + + this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ? + this.options.cookiesEnabled.replace('[', '').replace(']', '').replace(/ /g, '').toLowerCase().split(',') : this.options.cookiesEnabled; + + if (this.options.filterControl) { + var that = this; + this.$el.on('column-search.bs.table', function (e, field, text) { + var isNewField = true; + + for (var i = 0; i < that.options.filterControls.length; i++) { + if (that.options.filterControls[i].field === field) { + that.options.filterControls[i].text = text; + isNewField = false; + break; + } + } + if (isNewField) { + that.options.filterControls.push({ + field: field, + text: text + }); + } + + setCookie(that, cookieIds.filterControl, JSON.stringify(that.options.filterControls)); + }).on('post-body.bs.table', function () { + setTimeout(function () { + if (!that.options.filterControlValuesLoaded) { + that.options.filterControlValuesLoaded = true; + var filterControl = JSON.parse(getCookie(that, that.options.cookieIdTable, cookieIds.filterControl)); + if (filterControl) { + var field = null, + result = [], + header = getCurrentHeader(that), + searchControls = getCurrentSearchControls(that); + + header.find(searchControls).each(function (index, ele) { + field = $(this).parent().parent().parent().data('field'); + result = $.grep(filterControl, function (valueObj) { + return valueObj.field === field; + }); + + if (result.length > 0) { + $(this).val(result[0].text); + that.onColumnSearch({currentTarget: $(this)}); + } + }); + } + } + }, 250); + }); + } + _init.apply(this, Array.prototype.slice.apply(arguments)); + }; + + BootstrapTable.prototype.initTable = function () { + _initTable.apply(this, Array.prototype.slice.apply(arguments)); + this.initCookie(); + }; + + BootstrapTable.prototype.initCookie = function () { + if (!this.options.cookie) { + return; + } + + if ((this.options.cookieIdTable === '') || (this.options.cookieExpire === '') || (!cookieEnabled())) { + throw new Error("Configuration error. Please review the cookieIdTable, cookieExpire properties, if those properties are ok, then this browser does not support the cookies"); + return; + } + + var sortOrderCookie = getCookie(this, this.options.cookieIdTable, cookieIds.sortOrder), + sortOrderNameCookie = getCookie(this, this.options.cookieIdTable, cookieIds.sortName), + pageNumberCookie = getCookie(this, this.options.cookieIdTable, cookieIds.pageNumber), + pageListCookie = getCookie(this, this.options.cookieIdTable, cookieIds.pageList), + columnsCookie = JSON.parse(getCookie(this, this.options.cookieIdTable, cookieIds.columns)), + searchTextCookie = getCookie(this, this.options.cookieIdTable, cookieIds.searchText); + + //sortOrder + this.options.sortOrder = sortOrderCookie ? sortOrderCookie : 'asc'; + //sortName + this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : undefined; + //pageNumber + this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber; + //pageSize + this.options.pageSize = pageListCookie ? pageListCookie === this.options.formatAllRows() ? pageListCookie : +pageListCookie : this.options.pageSize; + //searchText + this.options.searchText = searchTextCookie ? searchTextCookie : ''; + + if (columnsCookie) { + $.each(this.columns, function (i, column) { + column.visible = $.inArray(column.field, columnsCookie) !== -1; + }); + } + }; + + BootstrapTable.prototype.onSort = function () { + _onSort.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.sortOrder, this.options.sortOrder); + setCookie(this, cookieIds.sortName, this.options.sortName); + }; + + BootstrapTable.prototype.onPageNumber = function () { + _onPageNumber.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageNumber, this.options.pageNumber); + }; + + BootstrapTable.prototype.onPageListChange = function () { + _onPageListChange.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageList, this.options.pageSize); + }; + + BootstrapTable.prototype.onPageFirst = function () { + _onPageFirst.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageNumber, this.options.pageNumber); + }; + + BootstrapTable.prototype.onPagePre = function () { + _onPagePre.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageNumber, this.options.pageNumber); + }; + + BootstrapTable.prototype.onPageNext = function () { + _onPageNext.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageNumber, this.options.pageNumber); + }; + + BootstrapTable.prototype.onPageLast = function () { + _onPageLast.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.pageNumber, this.options.pageNumber); + }; + + BootstrapTable.prototype.toggleColumn = function () { + _toggleColumn.apply(this, Array.prototype.slice.apply(arguments)); + + var visibleColumns = []; + + $.each(this.columns, function (i, column) { + if (column.visible) { + visibleColumns.push(column.field); + } + }); + + setCookie(this, cookieIds.columns, JSON.stringify(visibleColumns)); + }; + + BootstrapTable.prototype.selectPage = function (page) { + _selectPage.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, idsStateSaveList.pageNumber, page); + }; + + BootstrapTable.prototype.onSearch = function () { + _onSearch.apply(this, Array.prototype.slice.apply(arguments)); + setCookie(this, cookieIds.searchText, this.searchText); + }; + + BootstrapTable.prototype.deleteCookie = function (cookieName) { + if ((cookieName === '') || (!cookieEnabled())) { + return; + } + + deleteCookie(this.options.cookieIdTable, cookieIds[cookieName], this.options.cookiePath, this.options.cookieDomain); + }; +})(jQuery); diff --git a/public/assets/js/extensions/editable/README.md b/public/assets/js/extensions/editable/README.md new file mode 100755 index 0000000000..041a14202e --- /dev/null +++ b/public/assets/js/extensions/editable/README.md @@ -0,0 +1,53 @@ +# Table Editable + +Use Plugin: [x-editable](https://github.com/vitalets/x-editable) + +## Usage + +```html + +``` + +## Options + +### editable + +* type: Boolean +* description: Set false to disabled editable of all columns. +* default: `true` + +## Column options + +### editable + +* type: Object +* description: Configuration of x-editable. Full list of options: http://vitalets.github.io/x-editable/docs.html#editable +* default: `undefined` + +## Events + +### onEditableInit(editable-init.bs.table) + +Fired when all columns was initialized by `$().editable()` method. + +### onEditableSave(editable-save.bs.table) + +Fired when an editable cell is saved. + +parameters: field, row, oldValue, $el + +### onEditableShown(editable-shown.bs.table) + +Fired when an editable cell is opened for edits. + +parameters: field, row, $el, editable + +### onEditableHidden(editable-hidden.bs.table) + +Fired when an editable cell is hidden / closed. + +parameters: field, row, $el, reason + +## The existing problems + +* Editable extension does not support searchable in the select type. diff --git a/public/assets/js/extensions/editable/bootstrap-table-editable.js b/public/assets/js/extensions/editable/bootstrap-table-editable.js new file mode 100755 index 0000000000..0bb43a6c21 --- /dev/null +++ b/public/assets/js/extensions/editable/bootstrap-table-editable.js @@ -0,0 +1,107 @@ +/** + * @author zhixin wen + * extensions: https://github.com/vitalets/x-editable + */ + +!function ($) { + + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + editable: true, + onEditableInit: function () { + return false; + }, + onEditableSave: function (field, row, oldValue, $el) { + return false; + }, + onEditableShown: function (field, row, $el, editable) { + return false; + }, + onEditableHidden: function (field, row, $el, reason) { + return false; + } + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'editable-init.bs.table': 'onEditableInit', + 'editable-save.bs.table': 'onEditableSave', + 'editable-shown.bs.table': 'onEditableShown', + 'editable-hidden.bs.table': 'onEditableHidden' + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initTable = BootstrapTable.prototype.initTable, + _initBody = BootstrapTable.prototype.initBody; + + BootstrapTable.prototype.initTable = function () { + var that = this; + _initTable.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.editable) { + return; + } + + $.each(this.columns, function (i, column) { + if (!column.editable) { + return; + } + + var _formatter = column.formatter; + column.formatter = function (value, row, index) { + var result = _formatter ? _formatter(value, row, index) : value; + + return ['' + '' + ].join(''); + }; + }); + }; + + BootstrapTable.prototype.initBody = function () { + var that = this; + _initBody.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.editable) { + return; + } + + $.each(this.columns, function (i, column) { + if (!column.editable) { + return; + } + + that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) + .off('save').on('save', function (e, params) { + var data = that.getData(), + index = $(this).parents('tr[data-index]').data('index'), + row = data[index], + oldValue = row[column.field]; + + row[column.field] = params.submitValue; + that.trigger('editable-save', column.field, row, oldValue, $(this)); + }); + that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) + .off('shown').on('shown', function (e, editable) { + var data = that.getData(), + index = $(this).parents('tr[data-index]').data('index'), + row = data[index]; + + that.trigger('editable-shown', column.field, row, $(this), editable); + }); + that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) + .off('hidden').on('hidden', function (e, reason) { + var data = that.getData(), + index = $(this).parents('tr[data-index]').data('index'), + row = data[index]; + + that.trigger('editable-hidden', column.field, row, $(this), reason); + }); + }); + this.trigger('editable-init'); + }; + +}(jQuery); diff --git a/public/assets/js/extensions/export/README.md b/public/assets/js/extensions/export/README.md new file mode 100755 index 0000000000..d8666893bc --- /dev/null +++ b/public/assets/js/extensions/export/README.md @@ -0,0 +1,35 @@ +# Table Export + +Use Plugin: [tableExport.jquery.plugin](https://github.com/hhurz/tableExport.jquery.plugin) + +## Usage + +```html + +``` + +## Options + +### showExport + +* type: Boolean +* description: set `true` to show export button. +* default: `false` + +### exportDataType + +* type: String +* description: export data type, support: 'basic', 'all', 'selected'. +* default: `basic` + +### exportTypes + +* type: Array +* description: export types, support types: 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'. +* default: `['json', 'xml', 'csv', 'txt', 'sql', 'excel']` + +### exportOptions + +* type: Object +* description: export [options](https://github.com/hhurz/tableExport.jquery.plugin#options) of `tableExport.jquery.plugin` +* default: `{}` diff --git a/public/assets/js/extensions/export/bootstrap-table-export.js b/public/assets/js/extensions/export/bootstrap-table-export.js new file mode 100755 index 0000000000..3669e3ebac --- /dev/null +++ b/public/assets/js/extensions/export/bootstrap-table-export.js @@ -0,0 +1,106 @@ +/** + * @author zhixin wen + * extensions: https://github.com/kayalshri/tableExport.jquery.plugin + */ + +(function ($) { + 'use strict'; + + var TYPE_NAME = { + json: 'JSON', + xml: 'XML', + png: 'PNG', + csv: 'CSV', + txt: 'TXT', + sql: 'SQL', + doc: 'MS-Word', + excel: 'Ms-Excel', + powerpoint: 'Ms-Powerpoint', + pdf: 'PDF' + }; + + $.extend($.fn.bootstrapTable.defaults, { + showExport: false, + exportDataType: 'basic', // basic, all, selected + // 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf' + exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'], + exportOptions: {} + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initToolbar = BootstrapTable.prototype.initToolbar; + + BootstrapTable.prototype.initToolbar = function () { + this.showToolbar = this.options.showExport; + + _initToolbar.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.showExport) { + var that = this, + $btnGroup = this.$toolbar.find('>.btn-group'), + $export = $btnGroup.find('div.export'); + + if (!$export.length) { + $export = $([ + '
', + '', + '', + '
'].join('')).appendTo($btnGroup); + + var $menu = $export.find('.dropdown-menu'), + exportTypes = this.options.exportTypes; + + if (typeof this.options.exportTypes === 'string') { + var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(','); + + exportTypes = []; + $.each(types, function (i, value) { + exportTypes.push(value.slice(1, -1)); + }); + } + $.each(exportTypes, function (i, type) { + if (TYPE_NAME.hasOwnProperty(type)) { + $menu.append(['
  • ', + '', + TYPE_NAME[type], + '', + '
  • '].join('')); + } + }); + + $menu.find('li').click(function () { + var type = $(this).data('type'), + doExport = function () { + that.$el.tableExport($.extend({}, that.options.exportOptions, { + type: type, + escape: false + })); + }; + + if (that.options.exportDataType === 'all' && that.options.pagination) { + that.togglePagination(); + that.$el.on('load-success.bs.table', function () { + doExport(); + that.$el.off('load-success.bs.table'); + that.togglePagination(); + }); + } else if (that.options.exportDataType === 'selected') { + var data = that.getData(), + selectedData = that.getAllSelections(); + + that.load(selectedData); + doExport(); + that.load(data); + } else { + doExport(); + } + }); + } + } + }; +})(jQuery); diff --git a/public/assets/js/extensions/export/jquery.base64.js b/public/assets/js/extensions/export/jquery.base64.js new file mode 100644 index 0000000000..937705ce3a --- /dev/null +++ b/public/assets/js/extensions/export/jquery.base64.js @@ -0,0 +1,189 @@ +/*jslint adsafe: false, bitwise: true, browser: true, cap: false, css: false, + debug: false, devel: true, eqeqeq: true, es5: false, evil: false, + forin: false, fragment: false, immed: true, laxbreak: false, newcap: true, + nomen: false, on: false, onevar: true, passfail: false, plusplus: true, + regexp: false, rhino: true, safe: false, strict: false, sub: false, + undef: true, white: false, widget: false, windows: false */ +/*global jQuery: false, window: false */ +//"use strict"; + +/* + * Original code (c) 2010 Nick Galbreath + * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript + * + * jQuery port (c) 2010 Carlo Zottmann + * http://github.com/carlo/jquery-base64 + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* base64 encode/decode compatible with window.btoa/atob + * + * window.atob/btoa is a Firefox extension to convert binary data (the "b") + * to base64 (ascii, the "a"). + * + * It is also found in Safari and Chrome. It is not available in IE. + * + * if (!window.btoa) window.btoa = $.base64.encode + * if (!window.atob) window.atob = $.base64.decode + * + * The original spec's for atob/btoa are a bit lacking + * https://developer.mozilla.org/en/DOM/window.atob + * https://developer.mozilla.org/en/DOM/window.btoa + * + * window.btoa and $.base64.encode takes a string where charCodeAt is [0,255] + * If any character is not [0,255], then an exception is thrown. + * + * window.atob and $.base64.decode take a base64-encoded string + * If the input length is not a multiple of 4, or contains invalid characters + * then an exception is thrown. + */ + +jQuery.base64 = ( function( $ ) { + + var _PADCHAR = "=", + _ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + _VERSION = "1.0"; + + + function _getbyte64( s, i ) { + // This is oddly fast, except on Chrome/V8. + // Minimal or no improvement in performance by using a + // object with properties mapping chars to value (eg. 'A': 0) + + var idx = _ALPHA.indexOf( s.charAt( i ) ); + + if ( idx === -1 ) { + throw "Cannot decode base64"; + } + + return idx; + } + + + function _decode( s ) { + var pads = 0, + i, + b10, + imax = s.length, + x = []; + + s = String( s ); + + if ( imax === 0 ) { + return s; + } + + if ( imax % 4 !== 0 ) { + throw "Cannot decode base64"; + } + + if ( s.charAt( imax - 1 ) === _PADCHAR ) { + pads = 1; + + if ( s.charAt( imax - 2 ) === _PADCHAR ) { + pads = 2; + } + + // either way, we want to ignore this last block + imax -= 4; + } + + for ( i = 0; i < imax; i += 4 ) { + b10 = ( _getbyte64( s, i ) << 18 ) | ( _getbyte64( s, i + 1 ) << 12 ) | ( _getbyte64( s, i + 2 ) << 6 ) | _getbyte64( s, i + 3 ); + x.push( String.fromCharCode( b10 >> 16, ( b10 >> 8 ) & 0xff, b10 & 0xff ) ); + } + + switch ( pads ) { + case 1: + b10 = ( _getbyte64( s, i ) << 18 ) | ( _getbyte64( s, i + 1 ) << 12 ) | ( _getbyte64( s, i + 2 ) << 6 ); + x.push( String.fromCharCode( b10 >> 16, ( b10 >> 8 ) & 0xff ) ); + break; + + case 2: + b10 = ( _getbyte64( s, i ) << 18) | ( _getbyte64( s, i + 1 ) << 12 ); + x.push( String.fromCharCode( b10 >> 16 ) ); + break; + } + + return x.join( "" ); + } + + + function _getbyte( s, i ) { + var x = s.charCodeAt( i ); + + if ( x > 255 ) { + throw "INVALID_CHARACTER_ERR: DOM Exception 5"; + } + + return x; + } + + + function _encode( s ) { + if ( arguments.length !== 1 ) { + throw "SyntaxError: exactly one argument required"; + } + + s = String( s ); + + var i, + b10, + x = [], + imax = s.length - s.length % 3; + + if ( s.length === 0 ) { + return s; + } + + for ( i = 0; i < imax; i += 3 ) { + b10 = ( _getbyte( s, i ) << 16 ) | ( _getbyte( s, i + 1 ) << 8 ) | _getbyte( s, i + 2 ); + x.push( _ALPHA.charAt( b10 >> 18 ) ); + x.push( _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) ); + x.push( _ALPHA.charAt( ( b10 >> 6 ) & 0x3f ) ); + x.push( _ALPHA.charAt( b10 & 0x3f ) ); + } + + switch ( s.length - imax ) { + case 1: + b10 = _getbyte( s, i ) << 16; + x.push( _ALPHA.charAt( b10 >> 18 ) + _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) + _PADCHAR + _PADCHAR ); + break; + + case 2: + b10 = ( _getbyte( s, i ) << 16 ) | ( _getbyte( s, i + 1 ) << 8 ); + x.push( _ALPHA.charAt( b10 >> 18 ) + _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) + _ALPHA.charAt( ( b10 >> 6 ) & 0x3f ) + _PADCHAR ); + break; + } + + return x.join( "" ); + } + + + return { + decode: _decode, + encode: _encode, + VERSION: _VERSION + }; + +}( jQuery ) ); diff --git a/public/assets/js/extensions/export/tableExport.js b/public/assets/js/extensions/export/tableExport.js new file mode 100644 index 0000000000..20e709fd16 --- /dev/null +++ b/public/assets/js/extensions/export/tableExport.js @@ -0,0 +1,359 @@ +/*The MIT License (MIT) + +Copyright (c) 2014 https://github.com/kayalshri/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.*/ + +(function($){ + $.fn.extend({ + tableExport: function(options) { + var defaults = { + separator: ',', + ignoreColumn: [], + tableName:'yourTableName', + type:'csv', + pdfFontSize:14, + pdfLeftMargin:20, + escape:'true', + htmlContent:'false', + consoleLog:'false' + }; + + var options = $.extend(defaults, options); + var el = this; + + if(defaults.type == 'csv' || defaults.type == 'txt'){ + + // Header + var tdData =""; + $(el).find('thead').find('tr').each(function() { + tdData += "\n"; + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + tdData += '"' + parseString($(this)) + '"' + defaults.separator; + } + } + + }); + tdData = $.trim(tdData); + tdData = $.trim(tdData).substring(0, tdData.length -1); + }); + + // Row vs Column + $(el).find('tbody').find('tr').each(function() { + tdData += "\n"; + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + tdData += '"'+ parseString($(this)) + '"'+ defaults.separator; + } + } + }); + //tdData = $.trim(tdData); + tdData = $.trim(tdData).substring(0, tdData.length -1); + }); + + //output + if(defaults.consoleLog == 'true'){ + console.log(tdData); + } + var base64data = "base64," + $.base64.encode(tdData); + window.open('data:application/'+defaults.type+';filename=exportData;' + base64data); + }else if(defaults.type == 'sql'){ + + // Header + var tdData ="INSERT INTO `"+defaults.tableName+"` ("; + $(el).find('thead').find('tr').each(function() { + + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + tdData += '`' + parseString($(this)) + '`,' ; + } + } + + }); + tdData = $.trim(tdData); + tdData = $.trim(tdData).substring(0, tdData.length -1); + }); + tdData += ") VALUES "; + // Row vs Column + $(el).find('tbody').find('tr').each(function() { + tdData += "("; + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + tdData += '"'+ parseString($(this)) + '",'; + } + } + }); + + tdData = $.trim(tdData).substring(0, tdData.length -1); + tdData += "),"; + }); + tdData = $.trim(tdData).substring(0, tdData.length -1); + tdData += ";"; + + //output + //console.log(tdData); + + if(defaults.consoleLog == 'true'){ + console.log(tdData); + } + + var base64data = "base64," + $.base64.encode(tdData); + window.open('data:application/sql;filename=exportData;' + base64data); + + + }else if(defaults.type == 'json'){ + + var jsonHeaderArray = []; + $(el).find('thead').find('tr').each(function() { + var tdData =""; + var jsonArrayTd = []; + + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + jsonArrayTd.push(parseString($(this))); + } + } + }); + jsonHeaderArray.push(jsonArrayTd); + + }); + + var jsonArray = []; + $(el).find('tbody').find('tr').each(function() { + var tdData =""; + var jsonArrayTd = []; + + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + jsonArrayTd.push(parseString($(this))); + } + } + }); + jsonArray.push(jsonArrayTd); + + }); + + var jsonExportArray =[]; + jsonExportArray.push({header:jsonHeaderArray,data:jsonArray}); + + //Return as JSON + //console.log(JSON.stringify(jsonExportArray)); + + //Return as Array + //console.log(jsonExportArray); + if(defaults.consoleLog == 'true'){ + console.log(JSON.stringify(jsonExportArray)); + } + var base64data = "base64," + $.base64.encode(JSON.stringify(jsonExportArray)); + window.open('data:application/json;filename=exportData;' + base64data); + }else if(defaults.type == 'xml'){ + + var xml = ''; + xml += ''; + + // Header + $(el).find('thead').find('tr').each(function() { + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + xml += "" + parseString($(this)) + ""; + } + } + }); + }); + xml += ''; + + // Row Vs Column + var rowCount=1; + $(el).find('tbody').find('tr').each(function() { + xml += ''; + var colCount=0; + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + xml += ""+parseString($(this))+""; + } + } + colCount++; + }); + rowCount++; + xml += ''; + }); + xml += '' + + if(defaults.consoleLog == 'true'){ + console.log(xml); + } + + var base64data = "base64," + $.base64.encode(xml); + window.open('data:application/xml;filename=exportData;' + base64data); + + }else if(defaults.type == 'excel' || defaults.type == 'doc'|| defaults.type == 'powerpoint' ){ + //console.log($(this).html()); + var excel=""; + // Header + $(el).find('thead').find('tr').each(function() { + excel += ""; + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + excel += ""; + } + } + }); + excel += ''; + + }); + + + // Row Vs Column + var rowCount=1; + $(el).find('tbody').find('tr').each(function() { + excel += ""; + var colCount=0; + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + excel += ""; + } + } + colCount++; + }); + rowCount++; + excel += ''; + }); + excel += '
    " + parseString($(this))+ "
    "+parseString($(this))+"
    ' + + if(defaults.consoleLog == 'true'){ + console.log(excel); + } + + var excelFile = ""; + excelFile += ""; + excelFile += ""; + excelFile += ""; + excelFile += ""; + excelFile += excel; + excelFile += ""; + excelFile += ""; + + var base64data = "base64," + $.base64.encode(excelFile); + window.open('data:application/vnd.ms-'+defaults.type+';filename=exportData.doc;' + base64data); + + }else if(defaults.type == 'png'){ + html2canvas($(el), { + onrendered: function(canvas) { + var img = canvas.toDataURL("image/png"); + window.open(img); + + + } + }); + }else if(defaults.type == 'pdf'){ + + var doc = new jsPDF('p','pt', 'a4', true); + doc.setFontSize(defaults.pdfFontSize); + + // Header + var startColPosition=defaults.pdfLeftMargin; + $(el).find('thead').find('tr').each(function() { + $(this).filter(':visible').find('th').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + var colPosition = startColPosition+ (index * 50); + doc.text(colPosition,20, parseString($(this))); + } + } + }); + }); + + + // Row Vs Column + var startRowPosition = 20; var page =1;var rowPosition=0; + $(el).find('tbody').find('tr').each(function(index,data) { + rowCalc = index+1; + + if (rowCalc % 26 == 0){ + doc.addPage(); + page++; + startRowPosition=startRowPosition+10; + } + rowPosition=(startRowPosition + (rowCalc * 10)) - ((page -1) * 280); + + $(this).filter(':visible').find('td').each(function(index,data) { + if ($(this).css('display') != 'none'){ + if(defaults.ignoreColumn.indexOf(index) == -1){ + var colPosition = startColPosition+ (index * 50); + doc.text(colPosition,rowPosition, parseString($(this))); + } + } + + }); + + }); + + // Output as Data URI + doc.output('datauri'); + + } + + + function parseString(data){ + + if(defaults.htmlContent == 'true'){ + content_data = data.html().trim(); + }else{ + content_data = data.text().trim(); + } + + if(defaults.escape == 'true'){ + content_data = escape(content_data); + } + + + + return content_data; + } + + } + }); + })(jQuery); + diff --git a/public/assets/js/extensions/filter-control/README.md b/public/assets/js/extensions/filter-control/README.md new file mode 100755 index 0000000000..b223102773 --- /dev/null +++ b/public/assets/js/extensions/filter-control/README.md @@ -0,0 +1,49 @@ +# Table Filter Control + +Use Plugin: [bootstrap-table-filter-control](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/filter-control)
    +Dependence if you use the datepicker option: [bootstrap-datepicker](https://github.com/eternicode/bootstrap-datepicker) v1.4.0 + +## Usage + +```html + +``` + +## Options + +### filterControl + +* type: Boolean +* description: Set true to add an `input` or `select` into the column. +* default: `false` + +### filterShowClear + +* type: Boolean +* description: Set true to add a button to clear all the controls added by this plugin +* default: `false` + + +## Column options + +### filterControl + +* type: String +* description: Set `input`: show an input control, `select`: show a select control, `datepicker`: show a datepicker control. +* default: `undefined` + +### filterDatepickerOptions +* type: Object +* description: If the datepicker option is set use this option to configure the datepicker with the native options. Use this way: `data-filter-datepicker-options='{"autoclose":true, "clearBtn": true, "todayHighlight": true}'`. +* default: `undefined` + +### filterStrictSearch +* type: Boolean +* description: Set to true if you want to use the strict search mode. +* default: `false` + +## Events + +### onColumnSearch(column-search.bs.table) + +* Fired when we are searching into the column data \ No newline at end of file diff --git a/public/assets/js/extensions/filter-control/bootstrap-table-filter-control.js b/public/assets/js/extensions/filter-control/bootstrap-table-filter-control.js new file mode 100755 index 0000000000..fa696d3bb2 --- /dev/null +++ b/public/assets/js/extensions/filter-control/bootstrap-table-filter-control.js @@ -0,0 +1,436 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + */ + +!function ($) { + + 'use strict'; + + var sprintf = $.fn.bootstrapTable.utils.sprintf; + + var addOptionToSelectControl = function (selectControl, value, text) { + selectControl = $(selectControl.get(selectControl.length - 1)); + if (existsOptionInSelectControl(selectControl, value)) { + selectControl.append($("") + .attr("value", value) + .text($('
    ').html(text).text())); + + // Sort it. Not overly efficient to do this here + var $opts = selectControl.find('option:gt(0)'); + $opts.sort(function (a, b) { + a = $(a).text().toLowerCase(); + b = $(b).text().toLowerCase(); + if ($.isNumeric(a) && $.isNumeric(b)) { + // Convert numerical values from string to float. + a = parseFloat(a); + b = parseFloat(b); + } + return a > b ? 1 : a < b ? -1 : 0; + }); + + selectControl.find('option:gt(0)').remove(); + selectControl.append($opts); + } + }; + + var existsOptionInSelectControl = function (selectControl, value) { + var options = selectControl.get(selectControl.length - 1).options; + for (var i = 0; i < options.length; i++) { + if (options[i].value === value.toString()) { + //The value is nor valid to add + return false; + } + } + + //If we get here, the value is valid to add + return true; + }; + + var fixHeaderCSS = function (that) { + that.$tableHeader.css('height', '77px'); + }; + + var getCurrentHeader = function (that) { + var header = that.$header; + if (that.options.height) { + header = that.$tableHeader; + } + + return header; + }; + + var getCurrentSearchControls = function (that) { + var searchControls = 'select, input'; + if (that.options.height) { + searchControls = 'table select, table input'; + } + + return searchControls; + }; + + var copyValues = function (that) { + var header = getCurrentHeader(that), + searchControls = getCurrentSearchControls(that); + + that.options.values = []; + + header.find(searchControls).each(function () { + that.options.values.push( + { + field: $(this).parent().parent().parent().data('field'), + value: $(this).val() + }); + }); + }; + + var setValues = function(that) { + var field = null, + result = [], + header = getCurrentHeader(that), + searchControls = getCurrentSearchControls(that); + + if (that.options.values.length > 0) { + header.find(searchControls).each(function (index, ele) { + field = $(this).parent().parent().parent().data('field'); + result = $.grep(that.options.values, function (valueObj) { + return valueObj.field === field; + }); + + if (result.length > 0) { + $(this).val(result[0].value); + } + }); + } + }; + + var createControls = function (that, header) { + var addedFilterControl = false, + isVisible, + html, + timeoutId = 0; + + $.each(that.columns, function (i, column) { + isVisible = 'hidden'; + html = []; + + if (!column.visible) { + return; + } + + if (!column.filterControl) { + html.push('
    '); + } else { + html.push('
    '); + + if (column.filterControl && column.searchable) { + addedFilterControl = true; + isVisible = 'visible' + } + switch (column.filterControl.toLowerCase()) { + case 'input' : + html.push(sprintf('', isVisible)); + break; + case 'select': + html.push(sprintf('', + column.field, isVisible)) + break; + case 'datepicker': + html.push(sprintf('', + column.field, isVisible)); + break; + } + } + + $.each(header.children().children(), function (i, tr) { + tr = $(tr); + if (tr.data('field') === column.field) { + tr.find('.fht-cell').append(html.join('')); + return false; + } + }); + if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') { + var filterDataType = column.filterData.substring(0, 3); + var filterDataSource = column.filterData.substring(4, column.filterData.length); + var selectControl = $('.' + column.field); + addOptionToSelectControl(selectControl, '', ''); + + switch (filterDataType) { + case 'url': + $.ajax({ + url: filterDataSource, + dataType: 'json', + success: function (data) { + $.each(data, function (key, value) { + addOptionToSelectControl(selectControl, key, value); + }); + } + }); + break; + case 'var': + var variableValues = window[filterDataSource]; + for (var key in variableValues) { + addOptionToSelectControl(selectControl, key, variableValues[key]); + } + break; + } + } + }); + + if (addedFilterControl) { + header.off('keyup', 'input').on('keyup', 'input', function (event) { + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + that.onColumnSearch(event); + }, that.options.searchTimeOut); + }); + + header.off('change', 'select').on('change', 'select', function (event) { + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + that.onColumnSearch(event); + }, that.options.searchTimeOut); + }); + + header.off('mouseup', 'input').on('mouseup', 'input', function (event) { + var $input = $(this), + oldValue = $input.val(); + + if (oldValue === "") { + return; + } + + setTimeout(function(){ + var newValue = $input.val(); + + if (newValue === "") { + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + that.onColumnSearch(event); + }, that.options.searchTimeOut); + } + }, 1); + }); + + if (header.find('.date-filter-control').length > 0) { + $.each(that.columns, function (i, column) { + if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'datepicker') { + header.find('.date-filter-control.' + column.field).datepicker(column.filterDatepickerOptions) + .on('changeDate', function (e) { + //Fired the keyup event + $(e.currentTarget).keyup(); + }); + } + }); + } + } else { + header.find('.filterControl').hide(); + } + }; + + $.extend($.fn.bootstrapTable.defaults, { + filterControl: false, + onColumnSearch: function (field, text) { + return false; + }, + filterShowClear: false, + //internal variables + values: [] + }); + + $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, { + filterControl: undefined, + filterData: undefined, + filterDatepickerOptions: undefined, + filterStrictSearch: false + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'column-search.bs.table': 'onColumnSearch' + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initToolbar = BootstrapTable.prototype.initToolbar, + _initHeader = BootstrapTable.prototype.initHeader, + _initBody = BootstrapTable.prototype.initBody, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.init = function () { + //Make sure that the filtercontrol option is set + if (this.options.filterControl) { + var that = this; + //Make sure that the internal variables are set correctly + this.options.values = []; + + this.$el.on('reset-view.bs.table', function () { + //Create controls on $tableHeader if the height is set + if (!that.options.height) { + return; + } + + //Avoid recreate the controls + if (that.$tableHeader.find('select').length > 0 || that.$tableHeader.find('input').length > 0) { + return; + } + + createControls(that, that.$tableHeader); + }).on('post-header.bs.table', function () { + setValues(that); + }).on('post-body.bs.table', function () { + if (that.options.height) { + fixHeaderCSS(that); + } + }).on('column-switch.bs.table', function(field, checked) { + setValues(that); + }); + } + _init.apply(this, Array.prototype.slice.apply(arguments)); + }; + + BootstrapTable.prototype.initToolbar = function () { + if ((!this.showToolbar) && (this.options.filterControl)) { + this.showToolbar = this.options.filterControl; + } + + _initToolbar.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.filterControl && this.options.filterShowClear) { + var $btnGroup = this.$toolbar.find('>.btn-group'), + $btnClear = $btnGroup.find('div.export'); + + if (!$btnClear.length) { + $btnClear = $([ + '', + ''].join('')).appendTo($btnGroup); + + $btnClear.off('click').on('click', $.proxy(this.clearFilterControl, this)); + } + } + }; + + BootstrapTable.prototype.initHeader = function () { + _initHeader.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.filterControl) { + return; + } + createControls(this, this.$header); + }; + + BootstrapTable.prototype.initBody = function () { + _initBody.apply(this, Array.prototype.slice.apply(arguments)); + + var that = this, + data = this.options.data, + pageTo = this.pageTo < this.options.data.length ? this.options.data.length : this.pageTo; + + for (var i = this.pageFrom - 1; i < pageTo; i++) { + var item = data[i]; + + $.each(this.header.fields, function (j, field) { + var value = item[field], + column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, field)]; + + value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[j], [value, item, i], value); + + if ((!column.checkbox) || (!column.radio)) { + if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'select' && column.searchable) { + if (column.filterData === undefined || column.filterData.toLowerCase() === 'column') { + var selectControl = $('.' + column.field); + if (selectControl !== undefined && selectControl.length > 0) { + if (selectControl.get(selectControl.length - 1).options.length === 0) { + //Added the default option + addOptionToSelectControl(selectControl, '', ''); + } + + //Added a new value + addOptionToSelectControl(selectControl, value, value); + } + } + } + } + }); + } + }; + + BootstrapTable.prototype.initSearch = function () { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + + var that = this; + var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial; + + //Check partial column filter + this.data = fp ? $.grep(this.data, function (item, i) { + for (var key in fp) { + var thisColumn = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)]; + var fval = fp[key].toLowerCase(); + var value = item[key]; + value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, + that.header.formatters[$.inArray(key, that.header.fields)], + [value, item, i], value); + + if(thisColumn.filterStrictSearch){ + if (!($.inArray(key, that.header.fields) !== -1 && + (typeof value === 'string' || typeof value === 'number') && + value.toString().toLowerCase() === fval.toString().toLowerCase())) { + return false; + } + } + else{ + if (!($.inArray(key, that.header.fields) !== -1 && + (typeof value === 'string' || typeof value === 'number') && + (value + '').toLowerCase().indexOf(fval) !== -1)) { + return false; + } + }; + } + return true; + }) : this.data; + }; + + BootstrapTable.prototype.onColumnSearch = function (event) { + copyValues(this); + var text = $.trim($(event.currentTarget).val()); + var $field = $(event.currentTarget).parent().parent().parent().data('field') + + if ($.isEmptyObject(this.filterColumnsPartial)) { + this.filterColumnsPartial = {}; + } + if (text) { + this.filterColumnsPartial[$field] = text; + } else { + delete this.filterColumnsPartial[$field]; + } + + this.options.pageNumber = 1; + this.onSearch(event); + this.updatePagination(); + this.trigger('column-search', $field, text); + }; + + BootstrapTable.prototype.clearFilterControl = function () { + if (this.options.filterControl && this.options.filterShowClear) { + $.each(this.options.values, function (i, item) { + item.value = ''; + }); + + setValues(this); + + var controls = getCurrentHeader(this).find(getCurrentSearchControls(this)), + timeoutId = 0; + + if (controls.length > 0) { + this.filterColumnsPartial = {}; + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + $(controls[0]).trigger(controls[0].tagName === 'INPUT' ? 'keyup' : 'change'); + }, this.options.searchTimeOut); + } + } + }; +}(jQuery); diff --git a/public/assets/js/extensions/filter/README.md b/public/assets/js/extensions/filter/README.md new file mode 100755 index 0000000000..15501f412f --- /dev/null +++ b/public/assets/js/extensions/filter/README.md @@ -0,0 +1,17 @@ +# Table Filter + +Use Plugin: [bootstrap table filters](https://github.com/lukaskral/bootstrap-table-filter) + +## Usage + +```html + +``` + +## Options + +### showFilter + +* type: Boolean +* description: set true to show filter menu. +* default: `false` diff --git a/public/assets/js/extensions/filter/bootstrap-table-filter.js b/public/assets/js/extensions/filter/bootstrap-table-filter.js new file mode 100755 index 0000000000..14af13da06 --- /dev/null +++ b/public/assets/js/extensions/filter/bootstrap-table-filter.js @@ -0,0 +1,67 @@ +/** + * @author zhixin wen + * extensions: https://github.com/lukaskral/bootstrap-table-filter + */ + +!function($) { + + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + showFilter: false + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.init = function () { + _init.apply(this, Array.prototype.slice.apply(arguments)); + + var that = this; + this.$el.on('load-success.bs.table', function () { + if (that.options.showFilter) { + $(that.options.toolbar).bootstrapTableFilter({ + connectTo: that.$el + }); + } + }); + }; + + BootstrapTable.prototype.initSearch = function () { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.sidePagination !== 'server') { + if (typeof this.searchCallback === 'function') { + this.data = $.grep(this.options.data, this.searchCallback); + } + } + }; + + BootstrapTable.prototype.getData = function () { + return (this.searchText || this.searchCallback) ? this.data : this.options.data; + }; + + BootstrapTable.prototype.getColumns = function () { + return this.columns; + }; + + BootstrapTable.prototype.registerSearchCallback = function (callback) { + this.searchCallback = callback; + }; + + BootstrapTable.prototype.updateSearch = function () { + this.options.pageNumber = 1; + this.initSearch(); + this.updatePagination(); + }; + + BootstrapTable.prototype.getServerUrl = function () { + return (this.options.sidePagination === 'server') ? this.options.url : false; + }; + + $.fn.bootstrapTable.methods.push('getColumns', + 'registerSearchCallback', 'updateSearch', + 'getServerUrl'); + +}(jQuery); \ No newline at end of file diff --git a/public/assets/js/extensions/flat-json/README.md b/public/assets/js/extensions/flat-json/README.md new file mode 100755 index 0000000000..f1c5c46d82 --- /dev/null +++ b/public/assets/js/extensions/flat-json/README.md @@ -0,0 +1,23 @@ +# Table flat-json + +Use Plugin: [bootstrap-table-flat-json](https://github.com/djhvscf/bootstrap-table-flat-json) + +## Usage + +```html + +``` + +## Options + +### flat + +* type: Boolean +* description: Set true to flat the JSON object. +* default: `false` + +### flatSeparator + +* type: String +* description: Set the default separator between object levels. +* default: `.` \ No newline at end of file diff --git a/public/assets/js/extensions/flat-json/bootstrap-table-flat-json.js b/public/assets/js/extensions/flat-json/bootstrap-table-flat-json.js new file mode 100755 index 0000000000..4bbf3a2a9e --- /dev/null +++ b/public/assets/js/extensions/flat-json/bootstrap-table-flat-json.js @@ -0,0 +1,62 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.3.0 + */ + +(function ($) { + 'use strict'; + + var flat = function (element, that) { + var result = {}; + + function recurse(cur, prop) { + if (Object(cur) !== cur) { + result[prop] = cur; + } else if ($.isArray(cur)) { + for (var i = 0, l = cur.length; i < l; i++) { + recurse(cur[i], prop ? prop + that.options.flatSeparator + i : "" + i); + if (l == 0) { + result[prop] = []; + } + } + } else { + var isEmpty = true; + for (var p in cur) { + isEmpty = false; + recurse(cur[p], prop ? prop + that.options.flatSeparator + p : p); + } + if (isEmpty) { + result[prop] = {}; + } + } + } + + recurse(element, ""); + return result; + }; + + var flatHelper = function (data, that) { + var flatArray = []; + + $.each(!$.isArray(data) ? [data] : data, function (i, element) { + flatArray.push(flat(element, that)); + }); + return flatArray; + }; + + $.extend($.fn.bootstrapTable.defaults, { + flat: false, + flatSeparator: '.' + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initData = BootstrapTable.prototype.initData; + + BootstrapTable.prototype.initData = function (data, type) { + if (this.options.flat) { + data = flatHelper(data ? data : this.options.data, this); + } + _initData.apply(this, [data, type]); + }; +})(jQuery); diff --git a/public/assets/js/extensions/group-by/README.md b/public/assets/js/extensions/group-by/README.md new file mode 100755 index 0000000000..95317dcfa0 --- /dev/null +++ b/public/assets/js/extensions/group-by/README.md @@ -0,0 +1,62 @@ +# Table group-by + +Use Plugin: [bootstrap-table-group-by](https://github.com/djhvscf/bootstrap-table-group-by)
    +Dependence: [jquery-treetable](https://github.com/ludo/jquery-treetable/) v3.2.0
    +You must include the bootstrap-table-group-by.css file in order to get the appropriate style + +## Usage + +```html + +``` + +## Options + +### groupBy + +* type: Boolean +* description: Set true to group the data by the field passed. +* default: `false` + +### groupByField + +* type: Array +* description: Set the array fields that you want to group the data. +* default: `[]` + +### groupBySumGroup + +* type: Boolean +* description: Set to True to include a sum per column. +* default: `false` + +### groupByInitExpanded + +* type: Boolean +* description: You can use the node number (parent row index) or you can use the `all` option in order to expand all nodes of the table. +* default: `undefined` + +## Methods + +### expandAll + +* Expand all the nodes in the table. + +### collapseAll + +* Collapse all the nodes in the table. + +## Column options + +### groupBySumGroup + +* type: Boolean +* description: Set to True to sum the column values. +* default: `false` + + +## Known issues + +### OnSort + +* When sort options are set to True the group by is not working properly, for now if these properties are set to True the group by extension will be disabled. \ No newline at end of file diff --git a/public/assets/js/extensions/group-by/bootstrap-table-group-by.css b/public/assets/js/extensions/group-by/bootstrap-table-group-by.css new file mode 100755 index 0000000000..fce5a9a7b1 --- /dev/null +++ b/public/assets/js/extensions/group-by/bootstrap-table-group-by.css @@ -0,0 +1,53 @@ +table.treetable tbody tr td { + cursor: default; +} + +table.treetable span { + background-position: center left; + background-repeat: no-repeat; + padding: .2em 0 .2em 1.5em; +} + +table.treetable tr.collapsed span.indenter a { + background-image: url(data:image/png;base64,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); + padding-right: 12px; +} + +table.treetable tr.expanded span.indenter a { + background-image: url(data:image/png;base64,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); + padding-right: 12px; +} + +table.treetable tr.branch { + background-color: #f9f9f9; +} + +table.treetable tr.selected { + background-color: #3875d7; + color: #fff; +} + +table.treetable tr span.indenter a { + outline: none; /* Expander shows outline after upgrading to 3.0 (#141) */ +} + +table.treetable tr.collapsed.selected span.indenter a { + background-image: url(data:image/png;base64,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); +} + +table.treetable tr.expanded.selected span.indenter a { + background-image: url(data:image/png;base64,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); +} + +table.treetable tr.accept { + background-color: #a3bce4; + color: #fff +} + +table.treetable tr.collapsed.accept td span.indenter a { + background-image: url(data:image/x-png;base64,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); +} + +table.treetable tr.expanded.accept td span.indenter a { + background-image: url(data:image/x-png;base64,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); +} \ No newline at end of file diff --git a/public/assets/js/extensions/group-by/bootstrap-table-group-by.js b/public/assets/js/extensions/group-by/bootstrap-table-group-by.js new file mode 100755 index 0000000000..6f95e61bdd --- /dev/null +++ b/public/assets/js/extensions/group-by/bootstrap-table-group-by.js @@ -0,0 +1,243 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.1.0 + */ + +!function ($) { + + 'use strict'; + + var originalRowAttr, + dataTTId = 'data-tt-id', + dataTTParentId = 'data-tt-parent-id', + obj = {}, + parentId = undefined; + + var getParentRowId = function (that, id) { + var parentRows = that.$body.find('tr').not('[' + 'data-tt-parent-id]'); + + for (var i = 0; i < parentRows.length; i++) { + if (i === id) { + return $(parentRows[i]).attr('data-tt-id'); + } + } + + return undefined; + }; + + var sumData = function (that, data) { + var sumRow = {}; + $.each(data, function (i, row) { + if (!row.IsParent) { + for (var prop in row) { + if (!isNaN(parseFloat(row[prop]))) { + if (that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, prop)].groupBySumGroup) { + if (sumRow[prop] === undefined) { + sumRow[prop] = 0; + } + sumRow[prop] += +row[prop]; + } + } + } + } + }); + return sumRow; + }; + + var rowAttr = function (row, index) { + //Call the User Defined Function + originalRowAttr.apply([row, index]); + + obj[dataTTId.toString()] = index; + + if (!row.IsParent) { + obj[dataTTParentId.toString()] = parentId === undefined ? index : parentId; + } else { + parentId = index; + delete obj[dataTTParentId.toString()]; + } + + return obj; + }; + + var setObjectKeys = function () { + // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys + Object.keys = function (o) { + if (o !== Object(o)) { + throw new TypeError('Object.keys called on a non-object'); + } + var k = [], + p; + for (p in o) { + if (Object.prototype.hasOwnProperty.call(o, p)) { + k.push(p); + } + } + return k; + } + }; + + var getDataArrayFromItem = function (that, item) { + var itemDataArray = []; + for (var i = 0; i < that.options.groupByField.length; i++) { + itemDataArray.push(item[that.options.groupByField[i]]); + } + + return itemDataArray; + }; + + var getNewRow = function (that, result, index) { + var newRow = {}; + for (var i = 0; i < that.options.groupByField.length; i++) { + newRow[that.options.groupByField[i].toString()] = result[index][0][that.options.groupByField[i]]; + } + + newRow.IsParent = true; + + return newRow; + }; + + var groupBy = function (array, f) { + var groups = {}; + $.each(array, function (i, o) { + var group = JSON.stringify(f(o)); + groups[group] = groups[group] || []; + groups[group].push(o); + }); + return Object.keys(groups).map(function (group) { + return groups[group]; + }); + }; + + var makeGrouped = function (that, data) { + var newData = [], + sumRow = {}; + + var result = groupBy(data, function (item) { + return getDataArrayFromItem(that, item); + }); + + for (var i = 0; i < result.length; i++) { + result[i].unshift(getNewRow(that, result, i)); + if (that.options.groupBySumGroup) { + sumRow = sumData(that, result[i]); + if (!$.isEmptyObject(sumRow)) { + result[i].push(sumRow); + } + } + } + + newData = newData.concat.apply(newData, result); + + if (!that.options.loaded && newData.length > 0) { + that.options.loaded = true; + that.options.originalData = that.options.data; + that.options.data = newData; + } + + return newData; + }; + + $.extend($.fn.bootstrapTable.defaults, { + groupBy: false, + groupByField: [], + groupBySumGroup: false, + groupByInitExpanded: undefined, //node, 'all' + //internal variables + loaded: false, + originalData: undefined + }); + + $.fn.bootstrapTable.methods.push('collapseAll', 'expandAll', 'refreshGroupByField'); + + $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, { + groupBySumGroup: false + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initData = BootstrapTable.prototype.initData; + + BootstrapTable.prototype.init = function () { + //Temporal validation + if (!this.options.sortName) { + if ((this.options.groupBy) && (this.options.groupByField.length > 0)) { + var that = this; + + // Compatibility: IE < 9 and old browsers + if (!Object.keys) { + setObjectKeys(); + } + + //Make sure that the internal variables are set correctly + this.options.loaded = false; + this.options.originalData = undefined; + + originalRowAttr = this.options.rowAttributes; + this.options.rowAttributes = rowAttr; + this.$el.on('post-body.bs.table', function () { + that.$el.treetable({ + expandable: true, + onNodeExpand: function () { + if (that.options.height) { + that.resetHeader(); + } + }, + onNodeCollapse: function () { + if (that.options.height) { + that.resetHeader(); + } + } + }, true); + + if (that.options.groupByInitExpanded !== undefined) { + if (typeof that.options.groupByInitExpanded === 'number') { + that.expandNode(that.options.groupByInitExpanded); + } else if (that.options.groupByInitExpanded.toLowerCase() === 'all') { + that.expandAll(); + } + } + }); + } + } + _init.apply(this, Array.prototype.slice.apply(arguments)); + }; + + BootstrapTable.prototype.initData = function (data, type) { + //Temporal validation + if (!this.options.sortName) { + if ((this.options.groupBy) && (this.options.groupByField.length > 0)) { + + this.options.groupByField = typeof this.options.groupByField === 'string' ? + this.options.groupByField.replace('[', '').replace(']', '') + .replace(/ /g, '').toLowerCase().split(',') : this.options.groupByField; + + data = makeGrouped(this, data ? data : this.options.data); + } + } + _initData.apply(this, [data, type]); + }; + + BootstrapTable.prototype.expandAll = function () { + this.$el.treetable('expandAll'); + }; + + BootstrapTable.prototype.collapseAll = function () { + this.$el.treetable('collapseAll'); + }; + + BootstrapTable.prototype.expandNode = function (id) { + id = getParentRowId(this, id); + if (id !== undefined) { + this.$el.treetable('expandNode', id); + } + }; + + BootstrapTable.prototype.refreshGroupByField = function (groupByFields) { + if (!$.fn.bootstrapTable.utils.compareObjects(this.options.groupByField, groupByFields)) { + this.options.groupByField = groupByFields; + this.load(this.options.originalData); + } + }; +}(jQuery); diff --git a/public/assets/js/extensions/key-events/README.md b/public/assets/js/extensions/key-events/README.md new file mode 100755 index 0000000000..efe21923bb --- /dev/null +++ b/public/assets/js/extensions/key-events/README.md @@ -0,0 +1,24 @@ +# Table Key Events + +Use Plugin: [bootstrap-table-key-events](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/key-events) + +## Usage + +```html + +``` + +## Options + +### keyEvents + +* type: Boolean +* description: +True to enable the key events. The key event list is: + * s: It will be focused the search textbox if it is enabled. + * r: It will refresh the table if the showRefresh option is enabled. + * t: It will toggle the table view if the showToggle option is enabled. + * p: It will fires the pagination switch if the showPaginationSwitch is enabled. + * left: It will go to prev page if the pagination is true. + * right: It will go to next page if the pagination is true. +* default: `false` diff --git a/public/assets/js/extensions/key-events/bootstrap-table-key-events.js b/public/assets/js/extensions/key-events/bootstrap-table-key-events.js new file mode 100755 index 0000000000..887f803562 --- /dev/null +++ b/public/assets/js/extensions/key-events/bootstrap-table-key-events.js @@ -0,0 +1,80 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + * + * @update zhixin wen + */ + +!function ($) { + + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + keyEvents: false + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init; + + BootstrapTable.prototype.init = function () { + _init.apply(this, Array.prototype.slice.apply(arguments)); + this.initKeyEvents(); + }; + + BootstrapTable.prototype.initKeyEvents = function () { + if (this.options.keyEvents) { + var that = this; + + $(document).off('keydown').on('keydown', function (e) { + var $search = that.$toolbar.find('.search input'), + $refresh = that.$toolbar.find('button[name="refresh"]'), + $toggle = that.$toolbar.find('button[name="toggle"]'), + $paginationSwitch = that.$toolbar.find('button[name="paginationSwitch"]'); + + if (document.activeElement === $search.get(0)) { + return true; + } + + switch (e.keyCode) { + case 83: //s + if (!that.options.search) { + return; + } + $search.focus(); + return false; + case 82: //r + if (!that.options.showRefresh) { + return; + } + $refresh.click(); + return false; + case 84: //t + if (!that.options.showToggle) { + return; + } + $toggle.click(); + return false; + case 80: //p + if (!that.options.showPaginationSwitch) { + return; + } + $paginationSwitch.click(); + return false; + case 37: // left + if (!that.options.pagination) { + return; + } + that.prevPage(); + return false; + case 39: // right + if (!that.options.pagination) { + return; + } + that.nextPage(); + return; + } + }); + } + }; +}(jQuery); diff --git a/public/assets/js/extensions/mobile/README.md b/public/assets/js/extensions/mobile/README.md new file mode 100755 index 0000000000..d526d782f3 --- /dev/null +++ b/public/assets/js/extensions/mobile/README.md @@ -0,0 +1,41 @@ +# Table Mobile + +Use Plugin: [bootstrap-table-mobile](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/mobile) + +## Usage + +```html + +``` + +## Options + +### mobileResponsive + +* type: Boolean +* description: Set true to change the view between card and table view depending on width and height given. +* default: `false` + +### checkOnInit + +* type: Boolean +* description: Set true to check the window size on init. +* default: `true` + +### minWidth + +* type: Integer +* description: Set the minimum width when the table will change the view. +* default: `562` + +### minHeight + +* type: Integer +* description: Set the minimum height when the table will change the view. +* default: `undefined` + +### columnsHidden + +* type: String +* description: Set the columns fields in this array in order to hide those columns in the cardView mode. Use this way in `data-*` configuration: ` data-columns-hidden="['name', 'description']"` or this way in javascript configuration: `columnsHidden = ['name', 'description']`. +* default: `undefined` diff --git a/public/assets/js/extensions/mobile/bootstrap-table-mobile.js b/public/assets/js/extensions/mobile/bootstrap-table-mobile.js new file mode 100755 index 0000000000..2a373a55b9 --- /dev/null +++ b/public/assets/js/extensions/mobile/bootstrap-table-mobile.js @@ -0,0 +1,129 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.1.0 + */ + +!function ($) { + + 'use strict'; + + var showHideColumns = function (that, checked) { + if (that.options.columnsHidden.length > 0 ) { + $.each(that.columns, function (i, column) { + if (that.options.columnsHidden.indexOf(column.field) !== -1) { + if (column.visible !== checked) { + that.toggleColumn($.fn.bootstrapTable.utils.getFieldIndex(that.columns, column.field), checked, true); + } + } + }); + } + }; + + var resetView = function (that) { + if (that.options.height || that.options.showFooter) { + setTimeout(that.resetView, 1); + } + }; + + var changeView = function (that, width, height) { + if (that.options.minHeight) { + if ((width <= that.options.minWidth) && (height <= that.options.minHeight)) { + conditionCardView(that); + } else if ((width > that.options.minWidth) && (height > that.options.minHeight)) { + conditionFullView(that); + } + } else { + if (width <= that.options.minWidth) { + conditionCardView(that); + } else if (width > that.options.minWidth) { + conditionFullView(that); + } + } + + resetView(that); + }; + + var conditionCardView = function (that) { + changeTableView(that, false); + showHideColumns(that, false); + }; + + var conditionFullView = function (that) { + changeTableView(that, true); + showHideColumns(that, true); + }; + + var changeTableView = function (that, cardViewState) { + that.options.cardView = cardViewState; + that.toggleView(); + }; + + var debounce = function(func,wait) { + var timeout; + return function() { + var context = this, + args = arguments; + var later = function() { + timeout = null; + func.apply(context,args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + $.extend($.fn.bootstrapTable.defaults, { + mobileResponsive: false, + minWidth: 562, + minHeight: undefined, + heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar + checkOnInit: true, + columnsHidden: [] + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init; + + BootstrapTable.prototype.init = function () { + _init.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.mobileResponsive) { + return; + } + + if (!this.options.minWidth) { + return; + } + + var that = this, + old = { + width: $(window).width(), + height: $(window).height() + }; + + $(window).on('resize orientationchange',debounce(function (evt) { + // reset view if height has only changed by at least the threshold. + var height = $(this).height(), + width = $(this).width(); + + if (Math.abs(old.height - height) > that.options.heightThreshold || old.width != width) { + changeView(that, width, height); + old = { + width: width, + height: height + }; + } + },200)); + + if (this.options.checkOnInit) { + var height = $(window).height(), + width = $(window).width(); + changeView(this, width, height); + old = { + width: width, + height: height + }; + } + }; +}(jQuery); diff --git a/public/assets/js/extensions/multiple-search/README.md b/public/assets/js/extensions/multiple-search/README.md new file mode 100755 index 0000000000..c12cf0ddf1 --- /dev/null +++ b/public/assets/js/extensions/multiple-search/README.md @@ -0,0 +1,17 @@ +# Table Multiple Search + +Use Plugin: [bootstrap-table-multiple-search](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-search) + +## Usage + +```html + +``` + +## Options + +### multipleSearch + +* type: Boolean +* description: Set to true if you want to search by multiple columns. For example: if the user puts: "526 table" we are going to `split` that string and then we are going to search in all columns in the boostrap table. +* default: `false` diff --git a/public/assets/js/extensions/multiple-search/bootstrap-table-multiple-search.js b/public/assets/js/extensions/multiple-search/bootstrap-table-multiple-search.js new file mode 100755 index 0000000000..22df2ae933 --- /dev/null +++ b/public/assets/js/extensions/multiple-search/bootstrap-table-multiple-search.js @@ -0,0 +1,67 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + */ + +!function ($) { + + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + multipleSearch: false + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.initSearch = function () { + if (this.options.multipleSearch) { + var strArray = this.searchText.split(" "), + that = this, + f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns, + dataFiltered = []; + + if (strArray.length === 1) { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + } else { + for (var i = 0; i < strArray.length; i++) { + var str = strArray[i].trim(); + dataFiltered = str ? $.grep(dataFiltered.length === 0 ? this.options.data : dataFiltered, function (item, i) { + for (var key in item) { + key = $.isNumeric(key) ? parseInt(key, 10) : key; + var value = item[key], + column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)], + j = $.inArray(key, that.header.fields); + + // Fix #142: search use formated data + if (column && column.searchFormatter) { + value = $.fn.bootstrapTable.utils.calculateObjectValue(column, + that.header.formatters[j], [value, item, i], value); + } + + var index = $.inArray(key, that.header.fields); + if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) { + if (that.options.strictSearch) { + if ((value + '').toLowerCase() === str) { + return true; + } + } else { + if ((value + '').toLowerCase().indexOf(str) !== -1) { + return true; + } + } + } + } + return false; + }) : this.data; + } + + this.data = dataFiltered; + } + } else { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + } + }; + +}(jQuery); diff --git a/public/assets/js/extensions/multiple-sort/README.md b/public/assets/js/extensions/multiple-sort/README.md new file mode 100755 index 0000000000..fc51b21d7d --- /dev/null +++ b/public/assets/js/extensions/multiple-sort/README.md @@ -0,0 +1,91 @@ +# Table Multiple Sort + +Use Plugin: [bootstrap-table-multiple-sort](https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort) + +## Usage + +```html + +``` + +## Options + +### showMultiSort + +* type: Boolean +* description: Set true to allow the multiple sort. +* default: `false` + +### sortPriority + +* type: Object +* description: Set one or multiple sort priority. Example: '[{"sortName": "forks_count","sortOrder":"desc"},{"sortName":"stargazers_count","sortOrder":"desc"}]' +* default: null + +### Icons +* sort: `glyphicon-sort` +* plus: `glyphicon-plus` +* minus: `glyphicon-minus` + +## Locales + +### formatMultipleSort + +* description: Title of the advanced search modal +* default: `Multiple Sort` + +### formatAddLevel + +* description: Text of the add level button +* default: `Add Level` + +### formatDeleteLevel + +* description: Text of the delete level button +* default: `Delete Level` + +### formatColumn + +* description: Text of Column header +* default: `Column` + +### formatOrder + +* description: Text of the delete level button +* default: `Order` + +### formatSortBy + +* description: Text of the delete level button +* default: `Sort by` + +### formatThenBy + +* description: Text of the delete level button +* default: `Then by` + +### formatSort + +* description: Text of the delete level button +* default: `Sort` + +### formatCancel + +* description: Text of the delete level button +* default: `Cancel` + +### formatDuplicateAlertTitle + +* description: Title of the duplicate alert +* default: `Duplicate(s) detected!` + +### formatDuplicateAlertDescription + +* description: Text of the duplicate alert +* default: `Please remove or change any duplicate column.` + +## Events + +### onMultipleSort(multiple-sort.bs.table) + +* Fires when sorting with one or multiple Sort Priority. diff --git a/public/assets/js/extensions/multiple-sort/bootstrap-table-multiple-sort.js b/public/assets/js/extensions/multiple-sort/bootstrap-table-multiple-sort.js new file mode 100755 index 0000000000..68f6a52f19 --- /dev/null +++ b/public/assets/js/extensions/multiple-sort/bootstrap-table-multiple-sort.js @@ -0,0 +1,378 @@ +/** + * @author Nadim Basalamah + * @version: v1.0.0 + * https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js + */ + +(function($) { + 'use strict'; + + var isSingleSort = false; + + var sort_order = { + asc: 'Ascending', + desc: 'Descending' + }; + + var showSortModal = function(that) { + var _selector = that.$sortModal.selector, + _id = _selector.substr(1); + + if (!$(_id).hasClass("modal")) { + var sModal = ' '; + + $("body").append($(sModal)); + + that.$sortModal = $(_selector); + var $rows = that.$sortModal.find("tbody > tr"); + + that.$sortModal.off('click', '#add').on('click', '#add', function() { + var total = that.$sortModal.find('.multi-sort-name:first option').length, + current = that.$sortModal.find('tbody tr').length; + + if (current < total) { + current++; + that.addLevel(); + that.setButtonStates(); + } + }); + + that.$sortModal.off('click', '#delete').on('click', '#delete', function() { + var total = that.$sortModal.find('.multi-sort-name:first option').length, + current = that.$sortModal.find('tbody tr').length; + + if (current > 1 && current <= total) { + current--; + that.$sortModal.find('tbody tr:last').remove(); + that.setButtonStates(); + } + }); + + that.$sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function() { + var $rows = that.$sortModal.find("tbody > tr"), + $alert = that.$sortModal.find('div.alert'), + fields = [], + results = []; + + + that.options.sortPriority = $.map($rows, function(row) { + var $row = $(row), + name = $row.find('.multi-sort-name').val(), + order = $row.find('.multi-sort-order').val(); + + fields.push(name); + + return { + sortName: name, + sortOrder: order + }; + }); + + var sorted_fields = fields.sort(); + + for (var i = 0; i < fields.length - 1; i++) { + if (sorted_fields[i + 1] == sorted_fields[i]) { + results.push(sorted_fields[i]); + } + } + + if (results.length > 0) { + if ($alert.length === 0) { + $alert = ''; + $($alert).insertBefore(that.$sortModal.find('.bars')); + } + } else { + if ($alert.length === 1) { + $($alert).remove(); + } + + that.options.sortName = ""; + that.onMultipleSort(); + that.$sortModal.modal('hide'); + } + }); + + if (that.options.sortPriority === null || that.options.sortPriority.length === 0) { + if (that.options.sortName) { + that.options.sortPriority = [{ + sortName: that.options.sortName, + sortOrder: that.options.sortOrder + }]; + } + } + + if (that.options.sortPriority !== null && that.options.sortPriority.length > 0) { + if ($rows.length < that.options.sortPriority.length && typeof that.options.sortPriority === 'object') { + for (var i = 0; i < that.options.sortPriority.length; i++) { + that.addLevel(i, that.options.sortPriority[i]); + } + } + } else { + that.addLevel(0); + } + + that.setButtonStates(); + } + }; + + $.extend($.fn.bootstrapTable.defaults, { + showMultiSort: false, + sortPriority: null, + onMultipleSort: function() { + return false; + } + }); + + $.extend($.fn.bootstrapTable.defaults.icons, { + sort: 'glyphicon-sort', + plus: 'glyphicon-plus', + minus: 'glyphicon-minus' + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'multiple-sort.bs.table': 'onMultipleSort' + }); + + $.extend($.fn.bootstrapTable.locales, { + formatMultipleSort: function() { + return 'Multiple Sort'; + }, + formatAddLevel: function() { + return "Add Level"; + }, + formatDeleteLevel: function() { + return "Delete Level"; + }, + formatColumn: function() { + return "Column"; + }, + formatOrder: function() { + return "Order"; + }, + formatSortBy: function() { + return "Sort by"; + }, + formatThenBy: function() { + return "Then by"; + }, + formatSort: function() { + return "Sort"; + }, + formatCancel: function() { + return "Cancel"; + }, + formatDuplicateAlertTitle: function() { + return "Duplicate(s) detected!"; + }, + formatDuplicateAlertDescription: function() { + return "Please remove or change any duplicate column."; + } + }); + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initToolbar = BootstrapTable.prototype.initToolbar; + + BootstrapTable.prototype.initToolbar = function() { + this.showToolbar = true; + var that = this, + sortModalId = '#sortModal_' + this.$el.attr('id'); + this.$sortModal = $(sortModalId); + + _initToolbar.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.showMultiSort) { + var $btnGroup = this.$toolbar.find('>.btn-group').first(), + $multiSortBtn = this.$toolbar.find('div.multi-sort'); + + if (!$multiSortBtn.length) { + $multiSortBtn = ' '; + + $btnGroup.append($multiSortBtn); + + showSortModal(that); + } + + this.$el.on('sort.bs.table', function() { + isSingleSort = true; + }); + + this.$el.on('multiple-sort.bs.table', function() { + isSingleSort = false; + }); + + this.$el.on('load-success.bs.table', function() { + if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') { + that.onMultipleSort(); + } + }); + + this.$el.on('column-switch.bs.table', function(field, checked) { + for (var i = 0; i < that.options.sortPriority.length; i++) { + if (that.options.sortPriority[i].sortName === checked) { + that.options.sortPriority.splice(i, 1); + } + } + + that.assignSortableArrows(); + that.$sortModal.remove(); + showSortModal(that); + }); + + this.$el.on('reset-view.bs.table', function() { + if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') { + that.assignSortableArrows(); + } + }); + } + }; + + BootstrapTable.prototype.onMultipleSort = function() { + var that = this; + + var cmp = function(x, y) { + return x > y ? 1 : x < y ? -1 : 0; + }; + + var arrayCmp = function(a, b) { + var arr1 = [], + arr2 = []; + + for (var i = 0; i < that.options.sortPriority.length; i++) { + var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1, + aa = a[that.options.sortPriority[i].sortName], + bb = b[that.options.sortPriority[i].sortName]; + + if (aa === undefined || aa === null) { + aa = ''; + } + if (bb === undefined || bb === null) { + bb = ''; + } + if ($.isNumeric(aa) && $.isNumeric(bb)) { + aa = parseFloat(aa); + bb = parseFloat(bb); + } + if (typeof aa !== 'string') { + aa = aa.toString(); + } + + arr1.push( + order * cmp(aa, bb)); + arr2.push( + order * cmp(bb, aa)); + } + + return cmp(arr1, arr2); + }; + + this.data.sort(function(a, b) { + return arrayCmp(a, b); + }); + + this.initBody(); + this.assignSortableArrows(); + this.trigger('multiple-sort'); + }; + + BootstrapTable.prototype.addLevel = function(index, sortPriority) { + var text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy(); + + this.$sortModal.find('tbody') + .append($('') + .append($('').text(text)) + .append($('').append($(''))) + ); + + var $multiSortName = this.$sortModal.find('.multi-sort-name').last(), + $multiSortOrder = this.$sortModal.find('.multi-sort-order').last(); + + $.each(this.columns, function (i, column) { + if (column.sortable === false || column.visible === false) { + return true; + } + $multiSortName.append(''); + }); + + $.each(sort_order, function(value, order) { + $multiSortOrder.append(''); + }); + + if (sortPriority !== undefined) { + $multiSortName.find('option[value="' + sortPriority.sortName + '"]').attr("selected", true); + $multiSortOrder.find('option[value="' + sortPriority.sortOrder + '"]').attr("selected", true); + } + }; + + BootstrapTable.prototype.assignSortableArrows = function() { + var that = this, + headers = that.$header.find('th'); + + for (var i = 0; i < headers.length; i++) { + for (var c = 0; c < that.options.sortPriority.length; c++) { + if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) { + $(headers[i]).find('.sortable').removeClass('desc asc').addClass(that.options.sortPriority[c].sortOrder); + } + } + } + }; + + BootstrapTable.prototype.setButtonStates = function() { + var total = this.$sortModal.find('.multi-sort-name:first option').length, + current = this.$sortModal.find('tbody tr').length; + + if (current == total) { + this.$sortModal.find('#add').attr('disabled', 'disabled'); + } + if (current > 1) { + this.$sortModal.find('#delete').removeAttr('disabled'); + } + if (current < total) { + this.$sortModal.find('#add').removeAttr('disabled'); + } + if (current == 1) { + this.$sortModal.find('#delete').attr('disabled', 'disabled'); + } + }; +})(jQuery); diff --git a/public/assets/js/extensions/natural-sorting/README.md b/public/assets/js/extensions/natural-sorting/README.md new file mode 100755 index 0000000000..fbc01782a9 --- /dev/null +++ b/public/assets/js/extensions/natural-sorting/README.md @@ -0,0 +1,13 @@ +# Table Natural Sorting + +Use Plugin: [bootstrap-table-natural-sorting](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/natural-sorting) + +## Usage + +```html + +``` + +### Options + +* Just add data-sorter="alphanum" to any th \ No newline at end of file diff --git a/public/assets/js/extensions/natural-sorting/bootstrap-table-natural-sorting.js b/public/assets/js/extensions/natural-sorting/bootstrap-table-natural-sorting.js new file mode 100755 index 0000000000..8e84eb659b --- /dev/null +++ b/public/assets/js/extensions/natural-sorting/bootstrap-table-natural-sorting.js @@ -0,0 +1,47 @@ +/** + * @author: Brian Huisman + * @webSite: http://www.greywyvern.com + * @version: v1.0.0 + * JS function to allow natural sorting on bootstrap-table columns + * just add data-sorter="alphanum" to any th + * + * @update Dennis Hernández + */ + +function alphanum(a, b) { + function chunkify(t) { + var tz = [], + x = 0, + y = -1, + n = 0, + i, + j; + + while (i = (j = t.charAt(x++)).charCodeAt(0)) { + var m = (i === 46 || (i >= 48 && i <= 57)); + if (m !== n) { + tz[++y] = ""; + n = m; + } + tz[y] += j; + } + return tz; + } + + var aa = chunkify(a); + var bb = chunkify(b); + + for (x = 0; aa[x] && bb[x]; x++) { + if (aa[x] !== bb[x]) { + var c = Number(aa[x]), + d = Number(bb[x]); + + if (c == aa[x] && d == bb[x]) { + return c - d; + } else { + return (aa[x] > bb[x]) ? 1 : -1; + } + } + } + return aa.length - bb.length; +} \ No newline at end of file diff --git a/public/assets/js/extensions/reorder-columns/README.md b/public/assets/js/extensions/reorder-columns/README.md new file mode 100755 index 0000000000..3a7868db6f --- /dev/null +++ b/public/assets/js/extensions/reorder-columns/README.md @@ -0,0 +1,41 @@ +# Table Reorder Columns + +Use Plugin: [bootstrap-table-reorder-columns](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-columns)
    +Dependence: [dragTable](https://github.com/akottr/dragtable/) v2.0.14 (must include the css file),
    +[jquery-ui](https://code.jquery.com/ui/) v1.11 + + +## Usage + +```html + + + + +``` + +## Options + +### reorderableColumns + +* type: Boolean +* description: Set true to allow the reorder feature. +* default: `false` + +### maxMovingRows + +* type: Integer +* description: Moving only the header. Recommended for very large tables (cells > 1000) +* default: `10` + +### dragaccept + +* type: String +* description: Allow to drag only the rows that have the css class as attribute. +* default: `null` + +## Events + +### onReorderColumn(reorder-column.bs.table) + +Fired when the column was dropped, receive as parameter the new header fields order \ No newline at end of file diff --git a/public/assets/js/extensions/reorder-columns/bootstrap-table-reorder-columns.js b/public/assets/js/extensions/reorder-columns/bootstrap-table-reorder-columns.js new file mode 100755 index 0000000000..0c8b8b3f7e --- /dev/null +++ b/public/assets/js/extensions/reorder-columns/bootstrap-table-reorder-columns.js @@ -0,0 +1,121 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.1.0 + */ + +!function ($) { + + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + reorderableColumns: false, + maxMovingRows: 10, + onReorderColumn: function (headerFields) { + return false; + }, + dragaccept: null + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'reorder-column.bs.table': 'onReorderColumn' + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initHeader = BootstrapTable.prototype.initHeader, + _toggleColumn = BootstrapTable.prototype.toggleColumn, + _toggleView = BootstrapTable.prototype.toggleView, + _resetView = BootstrapTable.prototype.resetView; + + BootstrapTable.prototype.initHeader = function () { + _initHeader.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.reorderableColumns) { + return; + } + + this.makeRowsReorderable(); + }; + + BootstrapTable.prototype.toggleColumn = function () { + _toggleColumn.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.reorderableColumns) { + return; + } + + this.makeRowsReorderable(); + }; + + BootstrapTable.prototype.toggleView = function () { + _toggleView.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.reorderableColumns) { + return; + } + + if (this.options.cardView) { + return; + } + + this.makeRowsReorderable(); + }; + + BootstrapTable.prototype.resetView = function () { + _resetView.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.reorderableColumns) { + return; + } + + this.makeRowsReorderable(); + }; + + BootstrapTable.prototype.makeRowsReorderable = function () { + var that = this; + try { + $(this.$el).dragtable('destroy'); + } catch (e) {} + $(this.$el).dragtable({ + maxMovingRows: that.options.maxMovingRows, + dragaccept: that.options.dragaccept, + clickDelay:200, + beforeStop: function() { + var ths = [], + formatters = [], + columns = [], + columnsHidden = [], + columnIndex = -1; + that.$header.find('th').each(function (i) { + ths.push($(this).data('field')); + formatters.push($(this).data('formatter')); + }); + + //Exist columns not shown + if (ths.length < that.columns.length) { + columnsHidden = $.grep(that.columns, function (column) { + return !column.visible; + }); + for (var i = 0; i < columnsHidden.length; i++) { + ths.push(columnsHidden[i].field); + formatters.push(columnsHidden[i].formatter); + } + } + + for (var i = 0; i < ths.length; i++ ) { + columnIndex = $.fn.bootstrapTable.utils.getFieldIndex(that.columns, ths[i]); + if (columnIndex !== -1) { + columns.push(that.columns[columnIndex]); + that.columns.splice(columnIndex, 1); + } + } + + that.columns = that.columns.concat(columns); + that.header.fields = ths; + that.header.formatters = formatters; + that.resetView(); + that.trigger('reorder-column', ths); + } + }); + }; +}(jQuery); diff --git a/public/assets/js/extensions/reorder-rows/README.md b/public/assets/js/extensions/reorder-rows/README.md new file mode 100755 index 0000000000..07d83ea89a --- /dev/null +++ b/public/assets/js/extensions/reorder-rows/README.md @@ -0,0 +1,74 @@ +# Table Reorder Rows + +Use Plugin: [bootstrap-table-reorder-rows](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows)
    +Dependence: [tablednd](https://github.com/isocra/TableDnD) v0.9,
    +if you want you can include the bootstrap-table-reorder-rows.css file to use the default dragClass + + +## Usage + +```html + + + +``` + +## Options + +### reorderableRows + +* type: Boolean +* description: Set true to allow the reorder feature. +* default: `false` + +### onDragStyle + +* type: String +* description: This is the style that is assigned to the row during drag. There are limitations to the styles that can be associated with a row (such as you can't assign a border�well you can, but it won't be displayed). +* default: `null` + +### onDropStyle + +* type: String +* description: This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations to what you can do. Also this replaces the original style, so again consider using onDragClass which is simply added and then removed on drop. +* default: `null` + +### onDragClass + +* type: String +* description: This class is added for the duration of the drag and then removed when the row is dropped. It is more flexible than using onDragStyle since it can be inherited by the row cells and other content. +* default: `reorder_rows_onDragClass` + +### dragHandle + +* type: String +* description: This is the cursor to use +* default: `null` + +### useRowAttrFunc + +* type: Boolean +* description: This function must be use if your `tr` elements won't have the `id` attribute. If your `tr` elements don't have the `id` attribute this plugin don't fire the onDrop event. +* default: `false` + +### onReorderRowsDrag + +* type: Function +* description: Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the table and the row which the user has started to drag. +* default: `empty function` + +### onReorderRowsDrop + +* type: Function +* description: Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table and the row that was dropped. +* default: `empty function` + +## Events + +### onReorderRow(reorder-row.bs.table) + +Fired when the row was dropped, receive as parameter the new data order + +## The existing problems + +* After search if the user reorder the rows the data is not shown properly after that. \ No newline at end of file diff --git a/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.css b/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.css new file mode 100755 index 0000000000..412ff145e3 --- /dev/null +++ b/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.css @@ -0,0 +1,14 @@ +.reorder_rows_onDragClass td { + background-color: #eee; + -webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; + -webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; + -moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; + -box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; +} + +.reorder_rows_onDragClass td:last-child { + -webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; + -webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; + -moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset; + -box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset; +} \ No newline at end of file diff --git a/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.js b/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.js new file mode 100755 index 0000000000..c733717695 --- /dev/null +++ b/public/assets/js/extensions/reorder-rows/bootstrap-table-reorder-rows.js @@ -0,0 +1,115 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + */ + +!function ($) { + + 'use strict'; + + var isSearch = false; + + var rowAttr = function (row, index) { + return { + id: 'customId_' + index + }; + }; + + $.extend($.fn.bootstrapTable.defaults, { + reorderableRows: false, + onDragStyle: null, + onDropStyle: null, + onDragClass: "reorder_rows_onDragClass", + dragHandle: null, + useRowAttrFunc: false, + onReorderRowsDrag: function (table, row) { + return false; + }, + onReorderRowsDrop: function (table, row) { + return false; + }, + onReorderRow: function (newData) { + return false; + } + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'reorder-row.bs.table': 'onReorderRow' + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _init = BootstrapTable.prototype.init, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.init = function () { + + if (!this.options.reorderableRows) { + return; + } + + var that = this; + if (this.options.useRowAttrFunc) { + this.options.rowAttributes = rowAttr; + } + + var onPostBody = this.options.onPostBody; + this.options.onPostBody = function () { + setTimeout(function () { + that.makeRowsReorderable(); + onPostBody.apply(); + }, 1); + }; + + _init.apply(this, Array.prototype.slice.apply(arguments)); + }; + + BootstrapTable.prototype.initSearch = function () { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.reorderableRows) { + return; + } + + //Known issue after search if you reorder the rows the data is not display properly + //isSearch = true; + }; + + BootstrapTable.prototype.makeRowsReorderable = function () { + if (this.options.cardView) { + return; + } + + var that = this; + this.$el.tableDnD({ + onDragStyle: that.options.onDragStyle, + onDropStyle: that.options.onDropStyle, + onDragClass: that.options.onDragClass, + onDrop: that.onDrop, + onDragStart: that.options.onReorderRowsDrag, + dragHandle: that.options.dragHandle + }); + }; + + BootstrapTable.prototype.onDrop = function (table, droppedRow) { + var tableBs = $(table), + tableBsData = tableBs.data('bootstrap.table'), + tableBsOptions = tableBs.data('bootstrap.table').options, + row = null, + newData = []; + + for (var i = 0; i < table.tBodies[0].rows.length; i++) { + row = $(table.tBodies[0].rows[i]); + newData.push(tableBsOptions.data[row.data('index')]); + row.data('index', i).attr('data-index', i); + } + + tableBsOptions.data = newData; + + //Call the user defined function + tableBsOptions.onReorderRowsDrop.apply(table, [table, droppedRow]); + + //Call the event reorder-row + tableBsData.trigger('reorder-row', newData); + }; +}(jQuery); \ No newline at end of file diff --git a/public/assets/js/extensions/resizable/README.md b/public/assets/js/extensions/resizable/README.md new file mode 100755 index 0000000000..46e414ab13 --- /dev/null +++ b/public/assets/js/extensions/resizable/README.md @@ -0,0 +1,66 @@ +# Table Resizable + +Use Plugin: [bootstrap-table-resizable](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/resizable)
    +Dependence: [colResizable](https://github.com/alvaro-prieto/colResizable) v1.5 + +## Usage + +```html + +``` + +## Options + +### resizable + +* type: Boolean +* description: Set true to allow the resize in each column. +* default: `false` + +### liveDrag + +* type: Boolean +* description: When set to true the table layout is updated while dragging column anchors. liveDrag enabled is more CPU consuming so it is not recommended for slow computers, specially when dealing with huge or extremely complicated tables. +* default: `false` + +### fixed + +* type: Boolean +* description: It is used to set how the resize method works. In fixed mode resizing a column does not alter total table width, which means that when a column is expanded the next one shrinks. If fixed is set to false then table can change its width and each column can shrink or expand independently. +* default: `true` + +### headerOnly + +* type: Boolean +* description: This attribute can be used to prevent vertical expansion of the column anchors to fit the table height. If it is set to true, column handler's size will be bounded to the first row's vertical size. +* default: `false` + +### minWidth + +* type: Integer +* description: This value specifies the minimum width (measured in pixels) that is allowed for the columns. +* default: `15` + +### hoverCursor + +* type: String +* description: This attribute can be used to customize the cursor that will be displayed when the user is positioned on the column anchors. +* default: `e-resize` + +### dragCursor + +* type: String +* description: Defines the cursor that will be used while the user is resizing a column. +* default: `e-resize` + +### onResizableResize + +* type: Function +* description: If a callback function is supplied it will be fired when the user has ended dragging a column anchor altering the previous table layout. The callback function can obtain a reference to the updated table through the currentTarget attribute of the event retrieved by parameters. +* default: `empty function` + +### onResizableDrag + +* type: Function +* description: This event is fired while dragging a column anchor if liveDrag is enabled. It can be useful if the table is being used as a multiple range slider. The callback function can obtain a reference to the updated table through the currentTarget attribute of the event retrieved by parameters +* default: `empty function` \ No newline at end of file diff --git a/public/assets/js/extensions/resizable/bootstrap-table-resizable.js b/public/assets/js/extensions/resizable/bootstrap-table-resizable.js new file mode 100755 index 0000000000..8be7b09641 --- /dev/null +++ b/public/assets/js/extensions/resizable/bootstrap-table-resizable.js @@ -0,0 +1,74 @@ +/** + * @author: Dennis Hernández + * @webSite: http://djhvscf.github.io/Blog + * @version: v1.0.0 + */ + +(function ($) { + 'use strict'; + + var initResizable = function (that) { + //Deletes the plugin to re-create it + that.$el.colResizable({disable: true}); + + //Creates the plugin + that.$el.colResizable({ + liveDrag: that.options.liveDrag, + fixed: that.options.fixed, + headerOnly: that.options.headerOnly, + minWidth: that.options.minWidth, + hoverCursor: that.options.hoverCursor, + dragCursor: that.options.dragCursor, + onResize: that.onResize, + onDrag: that.options.onResizableDrag + }); + }; + + $.extend($.fn.bootstrapTable.defaults, { + resizable: false, + liveDrag: false, + fixed: true, + headerOnly: false, + minWidth: 15, + hoverCursor: 'e-resize', + dragCursor: 'e-resize', + onResizableResize: function (e) { + return false; + }, + onResizableDrag: function (e) { + return false; + } + }); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _toggleView = BootstrapTable.prototype.toggleView, + _resetView = BootstrapTable.prototype.resetView; + + BootstrapTable.prototype.toggleView = function () { + _toggleView.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.resizable && this.options.cardView) { + //Deletes the plugin + $(this.$el).colResizable({disable: true}); + } + }; + + BootstrapTable.prototype.resetView = function () { + var that = this; + + _resetView.apply(this, Array.prototype.slice.apply(arguments)); + + if (this.options.resizable) { + // because in fitHeader function, we use setTimeout(func, 100); + setTimeout(function () { + initResizable(that); + }, 100); + } + }; + + BootstrapTable.prototype.onResize = function (e) { + var that = $(e.currentTarget); + that.bootstrapTable('resetView'); + that.data('bootstrap.table').options.onResizableResize.apply(e); + } +})(jQuery); diff --git a/public/assets/js/extensions/toolbar/README.md b/public/assets/js/extensions/toolbar/README.md new file mode 100755 index 0000000000..b4a8a40abb --- /dev/null +++ b/public/assets/js/extensions/toolbar/README.md @@ -0,0 +1,53 @@ +# Table Toolbar + +Use Plugin: [bootstrap-table-toolbar](https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/toolbar) + +## Usage + +```html + +``` + +## Options + +### advancedSearch + +* type: Boolean +* description: Set true to allow the advanced search. +* default: `false` + +### idForm + +* type: String +* description: Must be set to know the idform. +* default: `advancedSearch` + +### actionForm + +* type: String +* description: Set the action of the form (pop-up). +* default: `` + +### idTable + +* type: String +* description: Set the id of the table to create the pop-up form. Required. +* default: `` + +## Locales + +### formatAdvancedSearch + +* description: Title of the advanced search modal +* default: `Advanced search` + +### formatAdvancedCloseButton + +* description: Text of the close button +* default: `Close` + +## Events + +### onColumnAdvancedSearch(column-advanced-search.bs.table) + +* Fired when we are searching into the advanced search form \ No newline at end of file diff --git a/public/assets/js/extensions/toolbar/bootstrap-table-toolbar.js b/public/assets/js/extensions/toolbar/bootstrap-table-toolbar.js new file mode 100755 index 0000000000..fd4e585933 --- /dev/null +++ b/public/assets/js/extensions/toolbar/bootstrap-table-toolbar.js @@ -0,0 +1,211 @@ +/** + * @author: aperez + * @version: v2.0.0 + * + * @update Dennis Hernández + */ + +!function($) { + 'use strict'; + + var firstLoad = false; + + var sprintf = $.fn.bootstrapTable.utils.sprintf; + + var showAvdSearch = function(pColumns, searchTitle, searchText, that) { + if (!$("#avdSearchModal" + "_" + that.options.idTable).hasClass("modal")) { + var vModal = sprintf("
    ", "_" + that.options.idTable); + vModal += "
    "; + vModal += "
    "; + vModal += "
    "; + vModal += " "; + vModal += sprintf("

    %s

    ", searchTitle); + vModal += "
    "; + vModal += "
    "; + vModal += sprintf("
    ", "_" + that.options.idTable); + vModal += "
    "; + vModal += "
    "; + vModal += "
    "; + vModal += "
    "; + vModal += "
    "; + + $("body").append($(vModal)); + + var vFormAvd = createFormAvd(pColumns, searchText, that), + timeoutId = 0;; + + $('#avdSearchModalContent' + "_" + that.options.idTable).append(vFormAvd.join('')); + + $('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) { + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + that.onColumnAdvancedSearch(event); + }, that.options.searchTimeOut); + }); + + $("#btnCloseAvd" + "_" + that.options.idTable).click(function() { + $("#avdSearchModal" + "_" + that.options.idTable).modal('hide'); + }); + + $("#avdSearchModal" + "_" + that.options.idTable).modal(); + } else { + $("#avdSearchModal" + "_" + that.options.idTable).modal(); + } + }; + + var createFormAvd = function(pColumns, searchText, that) { + var htmlForm = []; + htmlForm.push(sprintf('
    ', that.options.idForm, that.options.actionForm)); + for (var i in pColumns) { + var vObjCol = pColumns[i]; + if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) { + htmlForm.push('
    '); + htmlForm.push(sprintf('', vObjCol.title)); + htmlForm.push('
    '); + htmlForm.push(sprintf('', vObjCol.field, vObjCol.title, vObjCol.field)); + htmlForm.push('
    '); + htmlForm.push('
    '); + } + } + + htmlForm.push('
    '); + htmlForm.push('
    '); + htmlForm.push(sprintf('', "_" + that.options.idTable, searchText)); + htmlForm.push('
    '); + htmlForm.push('
    '); + htmlForm.push('
    '); + + return htmlForm; + }; + + $.extend($.fn.bootstrapTable.defaults, { + advancedSearch: false, + idForm: 'advancedSearch', + actionForm: '', + idTable: undefined, + onColumnAdvancedSearch: function (field, text) { + return false; + } + }); + + $.extend($.fn.bootstrapTable.defaults.icons, { + advancedSearchIcon: 'glyphicon-chevron-down' + }); + + $.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'column-advanced-search.bs.table': 'onColumnAdvancedSearch' + }); + + $.extend($.fn.bootstrapTable.locales, { + formatAdvancedSearch: function() { + return 'Advanced search'; + }, + formatAdvancedCloseButton: function() { + return "Close"; + } + }); + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales); + + var BootstrapTable = $.fn.bootstrapTable.Constructor, + _initToolbar = BootstrapTable.prototype.initToolbar, + _load = BootstrapTable.prototype.load, + _initSearch = BootstrapTable.prototype.initSearch; + + BootstrapTable.prototype.initToolbar = function() { + _initToolbar.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.search) { + return; + } + + if (!this.options.advancedSearch) { + return; + } + + if (!this.options.idTable) { + return; + } + + var that = this, + html = []; + + html.push(sprintf('
    ', this.options.buttonsAlign, this.options.buttonsAlign)); + html.push(sprintf('
    '); + + that.$toolbar.prepend(html.join('')); + + that.$toolbar.find('button[name="advancedSearch"]') + .off('click').on('click', function() { + showAvdSearch(that.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that); + }); + }; + + BootstrapTable.prototype.load = function(data) { + _load.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.advancedSearch) { + return; + } + + if (typeof this.options.idTable === 'undefined') { + return; + } else { + if (!firstLoad) { + var height = parseInt($(".bootstrap-table").height()); + height += 10; + $("#" + this.options.idTable).bootstrapTable("resetView", {height: height}); + firstLoad = true; + } + } + }; + + BootstrapTable.prototype.initSearch = function () { + _initSearch.apply(this, Array.prototype.slice.apply(arguments)); + + if (!this.options.advancedSearch) { + return; + } + + var that = this; + var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial; + + this.data = fp ? $.grep(this.data, function (item, i) { + for (var key in fp) { + var fval = fp[key].toLowerCase(); + var value = item[key]; + value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, + that.header.formatters[$.inArray(key, that.header.fields)], + [value, item, i], value); + + if (!($.inArray(key, that.header.fields) !== -1 && + (typeof value === 'string' || typeof value === 'number') && + (value + '').toLowerCase().indexOf(fval) !== -1)) { + return false; + } + } + return true; + }) : this.data; + }; + + BootstrapTable.prototype.onColumnAdvancedSearch = function (event) { + var text = $.trim($(event.currentTarget).val()); + var $field = $(event.currentTarget)[0].id; + + if ($.isEmptyObject(this.filterColumnsPartial)) { + this.filterColumnsPartial = {}; + } + if (text) { + this.filterColumnsPartial[$field] = text; + } else { + delete this.filterColumnsPartial[$field]; + } + + this.options.pageNumber = 1; + this.onSearch(event); + this.updatePagination(); + this.trigger('column-advanced-search', $field, text); + }; +}(jQuery); diff --git a/public/assets/js/libs/FileSaver/FileSaver.min.js b/public/assets/js/libs/FileSaver/FileSaver.min.js new file mode 100644 index 0000000000..c0792332af --- /dev/null +++ b/public/assets/js/libs/FileSaver/FileSaver.min.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(n){var o=t.createEvent("MouseEvents");o.initMouseEvent("click",!0,!1,e,0,0,0,0,0,!1,!1,!1,!1,0,null),n.dispatchEvent(o)},a=e.webkitRequestFileSystem,c=e.requestFileSystem||a||e.mozRequestFileSystem,u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},f="application/octet-stream",s=0,d=500,l=function(t){var o=function(){"string"==typeof t?n().revokeObjectURL(t):t.remove()};e.chrome?o():setTimeout(o,d)},v=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(i){u(i)}}},p=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob(["\ufeff",e],{type:e.type}):e},w=function(t,u){t=p(t);var d,w,y,m=this,S=t.type,h=!1,O=function(){v(m,"writestart progress write writeend".split(" "))},E=function(){if((h||!d)&&(d=n().createObjectURL(t)),w)w.location.href=d;else{var o=e.open(d,"_blank");void 0==o&&"undefined"!=typeof safari&&(e.location.href=d)}m.readyState=m.DONE,O(),l(d)},R=function(e){return function(){return m.readyState!==m.DONE?e.apply(this,arguments):void 0}},b={create:!0,exclusive:!1};return m.readyState=m.INIT,u||(u="download"),r?(d=n().createObjectURL(t),o.href=d,o.download=u,i(o),m.readyState=m.DONE,O(),void l(d)):(e.chrome&&S&&S!==f&&(y=t.slice||t.webkitSlice,t=y.call(t,0,t.size,f),h=!0),a&&"download"!==u&&(u+=".download"),(S===f||a)&&(w=e),c?(s+=t.size,void c(e.TEMPORARY,s,R(function(e){e.root.getDirectory("saved",b,R(function(e){var n=function(){e.getFile(u,b,R(function(e){e.createWriter(R(function(n){n.onwriteend=function(t){w.location.href=e.toURL(),m.readyState=m.DONE,v(m,"writeend",t),l(e)},n.onerror=function(){var e=n.error;e.code!==e.ABORT_ERR&&E()},"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=m["on"+e]}),n.write(t),m.abort=function(){n.abort(),m.readyState=m.DONE},m.readyState=m.WRITING}),E)}),E)};e.getFile(u,{create:!1},R(function(e){e.remove(),n()}),R(function(e){e.code===e.NOT_FOUND_ERR?n():E()}))}),E)}),E)):void E())},y=w.prototype,m=function(e,t){return new w(e,t)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t){return navigator.msSaveOrOpenBlob(p(e),t)}:(y.abort=function(){var e=this;e.readyState=e.DONE,v(e,"abort")},y.readyState=y.INIT=0,y.WRITING=1,y.DONE=2,y.error=y.onwritestart=y.onprogress=y.onwrite=y.onabort=y.onerror=y.onwriteend=null,m)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!=define.amd&&define([],function(){return saveAs}); \ No newline at end of file diff --git a/public/assets/js/libs/FileSaver/LICENSE.md b/public/assets/js/libs/FileSaver/LICENSE.md new file mode 100644 index 0000000000..9e3115bd5e --- /dev/null +++ b/public/assets/js/libs/FileSaver/LICENSE.md @@ -0,0 +1,9 @@ +Copyright © 2015 [Eli Grey][1]. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + [1]: http://eligrey.com diff --git a/public/assets/js/libs/html2canvas/LICENSE b/public/assets/js/libs/html2canvas/LICENSE new file mode 100644 index 0000000000..a73ffc9143 --- /dev/null +++ b/public/assets/js/libs/html2canvas/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 Niklas von Hertzen + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/public/assets/js/libs/html2canvas/html2canvas.min.js b/public/assets/js/libs/html2canvas/html2canvas.min.js new file mode 100644 index 0000000000..b3d8eb06d8 --- /dev/null +++ b/public/assets/js/libs/html2canvas/html2canvas.min.js @@ -0,0 +1,9 @@ +/* + html2canvas 0.5.0-alpha2 + Copyright (c) 2015 Niklas von Hertzen + + Released under MIT License +*/ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.html2canvas=e()}}(function(){var e;return function n(e,f,o){function d(t,l){if(!f[t]){if(!e[t]){var s="function"==typeof require&&require;if(!l&&s)return s(t,!0);if(i)return i(t,!0);var u=new Error("Cannot find module '"+t+"'");throw u.code="MODULE_NOT_FOUND",u}var a=f[t]={exports:{}};e[t][0].call(a.exports,function(n){var f=e[t][1][n];return d(f?f:n)},a,a.exports,n,e,f,o)}return f[t].exports}for(var i="function"==typeof require&&require,t=0;te;e+=2){var n=R[e],f=R[e+1];n(f),R[e]=void 0,R[e+1]=void 0}M=0}function y(){}function m(){return new TypeError("You cannot resolve a promise with itself")}function r(){return new TypeError("A promises callback cannot return that same promise.")}function v(e){try{return e.then}catch(n){return V.error=n,V}}function w(e,n,f,o){try{e.call(n,f,o)}catch(d){return d}}function b(e,n,f){N(function(e){var o=!1,d=w(f,n,function(f){o||(o=!0,n!==f?x(e,f):k(e,f))},function(n){o||(o=!0,q(e,n))},"Settle: "+(e._label||" unknown promise"));!o&&d&&(o=!0,q(e,d))},e)}function g(e,n){n._state===T?k(e,n._result):e._state===U?q(e,n._result):z(n,void 0,function(n){x(e,n)},function(n){q(e,n)})}function h(e,n){if(n.constructor===e.constructor)g(e,n);else{var f=v(n);f===V?q(e,V.error):void 0===f?k(e,n):i(f)?b(e,n,f):k(e,n)}}function x(e,n){e===n?q(e,m()):d(n)?h(e,n):k(e,n)}function j(e){e._onerror&&e._onerror(e._result),A(e)}function k(e,n){e._state===S&&(e._result=n,e._state=T,0===e._subscribers.length||N(A,e))}function q(e,n){e._state===S&&(e._state=U,e._result=n,N(j,e))}function z(e,n,f,o){var d=e._subscribers,i=d.length;e._onerror=null,d[i]=n,d[i+T]=f,d[i+U]=o,0===i&&e._state&&N(A,e)}function A(e){var n=e._subscribers,f=e._state;if(0!==n.length){for(var o,d,i=e._result,t=0;t1)throw new Error("Second argument not supported");if("object"!=typeof e)throw new TypeError("Argument must be an object");return l.prototype=e,new l},0),N=function(e,n){R[M]=e,R[M+1]=n,M+=2,2===M&&K()},O="undefined"!=typeof window?window:{},P=O.MutationObserver||O.WebKitMutationObserver,Q="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,R=new Array(1e3);K="undefined"!=typeof n&&"[object process]"==={}.toString.call(n)?s():P?u():Q?a():p();var S=void 0,T=1,U=2,V=new B,W=new B;F.prototype._validateInput=function(e){return L(e)},F.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},F.prototype._init=function(){this._result=new Array(this.length)};var X=F;F.prototype._enumerate=function(){for(var e=this.length,n=this.promise,f=this._input,o=0;n._state===S&&e>o;o++)this._eachEntry(f[o],o)},F.prototype._eachEntry=function(e,n){var f=this._instanceConstructor;t(e)?e.constructor===f&&e._state!==S?(e._onerror=null,this._settledAt(e._state,n,e._result)):this._willSettleAt(f.resolve(e),n):(this._remaining--,this._result[n]=this._makeResult(T,n,e))},F.prototype._settledAt=function(e,n,f){var o=this.promise;o._state===S&&(this._remaining--,this._abortOnReject&&e===U?q(o,f):this._result[n]=this._makeResult(e,n,f)),0===this._remaining&&k(o,this._result)},F.prototype._makeResult=function(e,n,f){return f},F.prototype._willSettleAt=function(e,n){var f=this;z(e,void 0,function(e){f._settledAt(T,n,e)},function(e){f._settledAt(U,n,e)})};var Y=function(e,n){return new X(this,e,!0,n).promise},Z=function(e,n){function f(e){x(i,e)}function o(e){q(i,e)}var d=this,i=new d(y,n);if(!L(e))return q(i,new TypeError("You must pass an array to race.")),i;for(var t=e.length,l=0;i._state===S&&t>l;l++)z(d.resolve(e[l]),void 0,f,o);return i},$=function(e,n){var f=this;if(e&&"object"==typeof e&&e.constructor===f)return e;var o=new f(y,n);return x(o,e),o},_=function(e,n){var f=this,o=new f(y,n);return q(o,e),o},en=0,nn=I;I.all=Y,I.race=Z,I.resolve=$,I.reject=_,I.prototype={constructor:I,then:function(e,n){var f=this,o=f._state;if(o===T&&!e||o===U&&!n)return this;var d=new this.constructor(y),i=f._result;if(o){var t=arguments[o-1];N(function(){D(o,d,t,i)})}else z(f,d,e,n);return d},"catch":function(e){return this.then(null,e)}};var fn=function(){var e;e="undefined"!=typeof o?o:"undefined"!=typeof window&&window.document?window:self;var n="Promise"in e&&"resolve"in e.Promise&&"reject"in e.Promise&&"all"in e.Promise&&"race"in e.Promise&&function(){var n;return new e.Promise(function(e){n=e}),i(n)}();n||(e.Promise=nn)},on={Promise:nn,polyfill:fn};"function"==typeof e&&e.amd?e(function(){return on}):"undefined"!=typeof f&&f.exports?f.exports=on:"undefined"!=typeof this&&(this.ES6Promise=on)}).call(this)}).call(this,n("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{_process:2}],2:[function(e,n){function f(){if(!t){t=!0;for(var e,n=i.length;n;){e=i,i=[];for(var f=-1;++fd;)n=e.charCodeAt(d++),n>=55296&&56319>=n&&i>d?(f=e.charCodeAt(d++),56320==(64512&f)?o.push(((1023&n)<<10)+(1023&f)+65536):(o.push(n),d--)):o.push(n);return o}function u(e){return t(e,function(e){var n="";return e>65535&&(e-=65536,n+=L(e>>>10&1023|55296),e=56320|1023&e),n+=L(e)}).join("")}function a(e){return 10>e-48?e-22:26>e-65?e-65:26>e-97?e-97:k}function p(e,n){return e+22+75*(26>e)-((0!=n)<<5)}function c(e,n,f){var o=0;for(e=f?K(e/B):e>>1,e+=K(e/n);e>J*z>>1;o+=k)e=K(e/J);return K(o+(J+1)*e/(e+A))}function y(e){var n,f,o,d,t,l,s,p,y,m,r=[],v=e.length,w=0,b=D,g=C;for(f=e.lastIndexOf(E),0>f&&(f=0),o=0;f>o;++o)e.charCodeAt(o)>=128&&i("not-basic"),r.push(e.charCodeAt(o));for(d=f>0?f+1:0;v>d;){for(t=w,l=1,s=k;d>=v&&i("invalid-input"),p=a(e.charCodeAt(d++)),(p>=k||p>K((j-w)/l))&&i("overflow"),w+=p*l,y=g>=s?q:s>=g+z?z:s-g,!(y>p);s+=k)m=k-y,l>K(j/m)&&i("overflow"),l*=m;n=r.length+1,g=c(w-t,n,0==t),K(w/n)>j-b&&i("overflow"),b+=K(w/n),w%=n,r.splice(w++,0,b)}return u(r)}function m(e){var n,f,o,d,t,l,u,a,y,m,r,v,w,b,g,h=[];for(e=s(e),v=e.length,n=D,f=0,t=C,l=0;v>l;++l)r=e[l],128>r&&h.push(L(r));for(o=d=h.length,d&&h.push(E);v>o;){for(u=j,l=0;v>l;++l)r=e[l],r>=n&&u>r&&(u=r);for(w=o+1,u-n>K((j-f)/w)&&i("overflow"),f+=(u-n)*w,n=u,l=0;v>l;++l)if(r=e[l],n>r&&++f>j&&i("overflow"),r==n){for(a=f,y=k;m=t>=y?q:y>=t+z?z:y-t,!(m>a);y+=k)g=a-m,b=k-m,h.push(L(p(m+g%b,0))),a=K(g/b);h.push(L(p(a,0))),t=c(f,w,o==d),f=0,++o}++f,++n}return h.join("")}function r(e){return l(e,function(e){return F.test(e)?y(e.slice(4).toLowerCase()):e})}function v(e){return l(e,function(e){return G.test(e)?"xn--"+m(e):e})}var w="object"==typeof o&&o,b="object"==typeof f&&f&&f.exports==w&&f,g="object"==typeof n&&n;(g.global===g||g.window===g)&&(d=g);var h,x,j=2147483647,k=36,q=1,z=26,A=38,B=700,C=72,D=128,E="-",F=/^xn--/,G=/[^ -~]/,H=/\x2E|\u3002|\uFF0E|\uFF61/g,I={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},J=k-q,K=Math.floor,L=String.fromCharCode;if(h={version:"1.2.4",ucs2:{decode:s,encode:u},decode:y,encode:m,toASCII:v,toUnicode:r},"function"==typeof e&&"object"==typeof e.amd&&e.amd)e("punycode",function(){return h});else if(w&&!w.nodeType)if(b)b.exports=h;else for(x in h)h.hasOwnProperty(x)&&(w[x]=h[x]);else d.punycode=h}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],4:[function(e,n){function f(e,n,f){!e.defaultView||n===e.defaultView.pageXOffset&&f===e.defaultView.pageYOffset||e.defaultView.scrollTo(n,f)}function o(e,n){try{n&&(n.width=e.width,n.height=e.height,n.getContext("2d").putImageData(e.getContext("2d").getImageData(0,0,e.width,e.height),0,0))}catch(f){t("Unable to copy canvas content from",e,f)}}function d(e,n){for(var f=3===e.nodeType?document.createTextNode(e.nodeValue):e.cloneNode(!1),i=e.firstChild;i;)(n===!0||1!==i.nodeType||"SCRIPT"!==i.nodeName)&&f.appendChild(d(i,n)),i=i.nextSibling;return 1===e.nodeType&&(f._scrollTop=e.scrollTop,f._scrollLeft=e.scrollLeft,"CANVAS"===e.nodeName?o(e,f):("TEXTAREA"===e.nodeName||"SELECT"===e.nodeName)&&(f.value=e.value)),f}function i(e){if(1===e.nodeType){e.scrollTop=e._scrollTop,e.scrollLeft=e._scrollLeft;for(var n=e.firstChild;n;)i(n),n=n.nextSibling}}var t=e("./log"),l=e("./promise");n.exports=function(e,n,o,t,s,u,a){var p=d(e.documentElement,s.javascriptEnabled),c=n.createElement("iframe");return c.className="html2canvas-container",c.style.visibility="hidden",c.style.position="fixed",c.style.left="-10000px",c.style.top="0px",c.style.border="0",c.width=o,c.height=t,c.scrolling="no",n.body.appendChild(c),new l(function(n){var o=c.contentWindow.document;c.contentWindow.onload=c.onload=function(){var e=setInterval(function(){o.body.childNodes.length>0&&(i(o.documentElement),clearInterval(e),"view"===s.type&&(c.contentWindow.scrollTo(u,a),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||c.contentWindow.scrollY===a&&c.contentWindow.scrollX===u||(o.documentElement.style.top=-a+"px",o.documentElement.style.left=-u+"px",o.documentElement.style.position="absolute")),n(c))},50)},o.open(),o.write(""),f(e,u,a),o.replaceChild(o.adoptNode(p),o.documentElement),o.close()})}},{"./log":15,"./promise":18}],5:[function(e,n){function f(e){this.r=0,this.g=0,this.b=0,this.a=null;this.fromArray(e)||this.namedColor(e)||this.rgb(e)||this.rgba(e)||this.hex6(e)||this.hex3(e)}f.prototype.darken=function(e){var n=1-e;return new f([Math.round(this.r*n),Math.round(this.g*n),Math.round(this.b*n),this.a])},f.prototype.isTransparent=function(){return 0===this.a},f.prototype.isBlack=function(){return 0===this.r&&0===this.g&&0===this.b},f.prototype.fromArray=function(e){return Array.isArray(e)&&(this.r=Math.min(e[0],255),this.g=Math.min(e[1],255),this.b=Math.min(e[2],255),e.length>3&&(this.a=e[3])),Array.isArray(e)};var o=/^#([a-f0-9]{3})$/i;f.prototype.hex3=function(e){var n=null;return null!==(n=e.match(o))&&(this.r=parseInt(n[1][0]+n[1][0],16),this.g=parseInt(n[1][1]+n[1][1],16),this.b=parseInt(n[1][2]+n[1][2],16)),null!==n};var d=/^#([a-f0-9]{6})$/i;f.prototype.hex6=function(e){var n=null;return null!==(n=e.match(d))&&(this.r=parseInt(n[1].substring(0,2),16),this.g=parseInt(n[1].substring(2,4),16),this.b=parseInt(n[1].substring(4,6),16)),null!==n};var i=/^rgb\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3})\)$/;f.prototype.rgb=function(e){var n=null;return null!==(n=e.match(i))&&(this.r=Number(n[1]),this.g=Number(n[2]),this.b=Number(n[3])),null!==n};var t=/^rgba\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *, *(\d+\.?\d*)\)$/;f.prototype.rgba=function(e){var n=null;return null!==(n=e.match(t))&&(this.r=Number(n[1]),this.g=Number(n[2]),this.b=Number(n[3]),this.a=Number(n[4])),null!==n},f.prototype.toString=function(){return null!==this.a&&1!==this.a?"rgba("+[this.r,this.g,this.b,this.a].join(",")+")":"rgb("+[this.r,this.g,this.b].join(",")+")"},f.prototype.namedColor=function(e){var n=l[e.toLowerCase()];if(n)this.r=n[0],this.g=n[1],this.b=n[2];else if("transparent"===e.toLowerCase())return this.r=this.g=this.b=this.a=0,!0;return!!n},f.prototype.isColor=!0;var l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};n.exports=f},{}],6:[function(e,n){function f(e,n){var f=j++;if(n=n||{},n.logging&&(window.html2canvas.logging=!0,window.html2canvas.start=Date.now()),n.async="undefined"==typeof n.async?!0:n.async,n.allowTaint="undefined"==typeof n.allowTaint?!1:n.allowTaint,n.removeContainer="undefined"==typeof n.removeContainer?!0:n.removeContainer,n.javascriptEnabled="undefined"==typeof n.javascriptEnabled?!1:n.javascriptEnabled,n.imageTimeout="undefined"==typeof n.imageTimeout?1e4:n.imageTimeout,n.renderer="function"==typeof n.renderer?n.renderer:c,n.strict=!!n.strict,"string"==typeof e){if("string"!=typeof n.proxy)return a.reject("Proxy must be used when rendering url");var i=null!=n.width?n.width:window.innerWidth,t=null!=n.height?n.height:window.innerHeight;return g(u(e),n.proxy,document,i,t,n).then(function(e){return d(e.contentWindow.document.documentElement,e,n,i,t)})}var l=(void 0===e?[document.documentElement]:e.length?e:[e])[0];return l.setAttribute(x+f,f),o(l.ownerDocument,n,l.ownerDocument.defaultView.innerWidth,l.ownerDocument.defaultView.innerHeight,f).then(function(e){return"function"==typeof n.onrendered&&(v("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),n.onrendered(e)),e})}function o(e,n,f,o,i){return b(e,e,f,o,n,e.defaultView.pageXOffset,e.defaultView.pageYOffset).then(function(t){v("Document cloned");var l=x+i,s="["+l+"='"+i+"']";e.querySelector(s).removeAttribute(l);var u=t.contentWindow,p=u.document.querySelector(s),c=a.resolve("function"==typeof n.onclone?n.onclone(u.document):!0);return c.then(function(){return d(p,t,n,f,o)})})}function d(e,n,f,o,d){var u=n.contentWindow,a=new p(u.document),c=new y(f,a),r=h(e),w="view"===f.type?o:l(u.document),b="view"===f.type?d:s(u.document),g=new f.renderer(w,b,c,f,document),x=new m(e,g,a,c,f);return x.ready.then(function(){v("Finished rendering");var o;return o="view"===f.type?t(g.canvas,{width:g.canvas.width,height:g.canvas.height,top:0,left:0,x:0,y:0}):e===u.document.body||e===u.document.documentElement||null!=f.canvas?g.canvas:t(g.canvas,{width:null!=f.width?f.width:r.width,height:null!=f.height?f.height:r.height,top:r.top,left:r.left,x:u.pageXOffset,y:u.pageYOffset}),i(n,f),o})}function i(e,n){n.removeContainer&&(e.parentNode.removeChild(e),v("Cleaned up container"))}function t(e,n){var f=document.createElement("canvas"),o=Math.min(e.width-1,Math.max(0,n.left)),d=Math.min(e.width,Math.max(1,n.left+n.width)),i=Math.min(e.height-1,Math.max(0,n.top)),t=Math.min(e.height,Math.max(1,n.top+n.height));return f.width=n.width,f.height=n.height,v("Cropping canvas at:","left:",n.left,"top:",n.top,"width:",d-o,"height:",t-i),v("Resulting crop with width",n.width,"and height",n.height," with x",o,"and y",i),f.getContext("2d").drawImage(e,o,i,d-o,t-i,n.x,n.y,d-o,t-i),f}function l(e){return Math.max(Math.max(e.body.scrollWidth,e.documentElement.scrollWidth),Math.max(e.body.offsetWidth,e.documentElement.offsetWidth),Math.max(e.body.clientWidth,e.documentElement.clientWidth))}function s(e){return Math.max(Math.max(e.body.scrollHeight,e.documentElement.scrollHeight),Math.max(e.body.offsetHeight,e.documentElement.offsetHeight),Math.max(e.body.clientHeight,e.documentElement.clientHeight))}function u(e){var n=document.createElement("a");return n.href=e,n.href=n.href,n}var a=e("./promise"),p=e("./support"),c=e("./renderers/canvas"),y=e("./imageloader"),m=e("./nodeparser"),r=e("./nodecontainer"),v=e("./log"),w=e("./utils"),b=e("./clone"),g=e("./proxy").loadUrlDocument,h=w.getBounds,x="data-html2canvas-node",j=0;f.Promise=a,f.CanvasRenderer=c,f.NodeContainer=r,f.log=v,f.utils=w,n.exports="undefined"==typeof document||"function"!=typeof Object.create||"function"!=typeof document.createElement("canvas").getContext?function(){return a.reject("No canvas support")}:f},{"./clone":4,"./imageloader":13,"./log":15,"./nodecontainer":16,"./nodeparser":17,"./promise":18,"./proxy":19,"./renderers/canvas":23,"./support":25,"./utils":29}],7:[function(e,n){function f(e){if(this.src=e,d("DummyImageContainer for",e),!this.promise||!this.image){d("Initiating DummyImageContainer"),f.prototype.image=new Image;var n=this.image;f.prototype.promise=new o(function(e,f){n.onload=e,n.onerror=f,n.src=i(),n.complete===!0&&e(n)})}}var o=e("./promise"),d=e("./log"),i=e("./utils").smallImage;n.exports=f},{"./log":15,"./promise":18,"./utils":29}],8:[function(e,n){function f(e,n){var f,d,i=document.createElement("div"),t=document.createElement("img"),l=document.createElement("span"),s="Hidden Text";i.style.visibility="hidden",i.style.fontFamily=e,i.style.fontSize=n,i.style.margin=0,i.style.padding=0,document.body.appendChild(i),t.src=o(),t.width=1,t.height=1,t.style.margin=0,t.style.padding=0,t.style.verticalAlign="baseline",l.style.fontFamily=e,l.style.fontSize=n,l.style.margin=0,l.style.padding=0,l.appendChild(document.createTextNode(s)),i.appendChild(l),i.appendChild(t),f=t.offsetTop-l.offsetTop+1,i.removeChild(l),i.appendChild(document.createTextNode(s)),i.style.lineHeight="normal",t.style.verticalAlign="super",d=t.offsetTop-i.offsetTop+1,document.body.removeChild(i),this.baseline=f,this.lineWidth=1,this.middle=d}var o=e("./utils").smallImage;n.exports=f},{"./utils":29}],9:[function(e,n){function f(){this.data={}}var o=e("./font");f.prototype.getMetrics=function(e,n){return void 0===this.data[e+"-"+n]&&(this.data[e+"-"+n]=new o(e,n)),this.data[e+"-"+n]},n.exports=f},{"./font":8}],10:[function(e,n){function f(n,f,o){this.image=null,this.src=n;var t=this,l=i(n);this.promise=(f?new d(function(e){"about:blank"===n.contentWindow.document.URL||null==n.contentWindow.document.documentElement?n.contentWindow.onload=n.onload=function(){e(n)}:e(n)}):this.proxyLoad(o.proxy,l,o)).then(function(n){var f=e("./core");return f(n.contentWindow.document.documentElement,{type:"view",width:n.width,height:n.height,proxy:o.proxy,javascriptEnabled:o.javascriptEnabled,removeContainer:o.removeContainer,allowTaint:o.allowTaint,imageTimeout:o.imageTimeout/2})}).then(function(e){return t.image=e})}var o=e("./utils"),d=e("./promise"),i=o.getBounds,t=e("./proxy").loadUrlDocument;f.prototype.proxyLoad=function(e,n,f){var o=this.src;return t(o.src,e,o.ownerDocument,n.width,n.height,f)},n.exports=f},{"./core":6,"./promise":18,"./proxy":19,"./utils":29}],11:[function(e,n){function f(e){this.src=e.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=o.resolve(!0)}var o=e("./promise");f.prototype.TYPES={LINEAR:1,RADIAL:2},n.exports=f},{"./promise":18}],12:[function(e,n){function f(e,n){this.src=e,this.image=new Image;var f=this;this.tainted=null,this.promise=new o(function(o,d){f.image.onload=o,f.image.onerror=d,n&&(f.image.crossOrigin="anonymous"),f.image.src=e,f.image.complete===!0&&o(f.image)})}var o=e("./promise");n.exports=f},{"./promise":18}],13:[function(e,n){function f(e,n){this.link=null,this.options=e,this.support=n,this.origin=this.getOrigin(window.location.href)}var o=e("./promise"),d=e("./log"),i=e("./imagecontainer"),t=e("./dummyimagecontainer"),l=e("./proxyimagecontainer"),s=e("./framecontainer"),u=e("./svgcontainer"),a=e("./svgnodecontainer"),p=e("./lineargradientcontainer"),c=e("./webkitgradientcontainer"),y=e("./utils").bind;f.prototype.findImages=function(e){var n=[];return e.reduce(function(e,n){switch(n.node.nodeName){case"IMG":return e.concat([{args:[n.node.src],method:"url"}]);case"svg":case"IFRAME":return e.concat([{args:[n.node],method:n.node.nodeName}])}return e},[]).forEach(this.addImage(n,this.loadImage),this),n},f.prototype.findBackgroundImage=function(e,n){return n.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(e,this.loadImage),this),e},f.prototype.addImage=function(e,n){return function(f){f.args.forEach(function(o){this.imageExists(e,o)||(e.splice(0,0,n.call(this,f)),d("Added image #"+e.length,"string"==typeof o?o.substring(0,100):o))},this)}},f.prototype.hasImageBackground=function(e){return"none"!==e.method},f.prototype.loadImage=function(e){if("url"===e.method){var n=e.args[0];return!this.isSVG(n)||this.support.svg||this.options.allowTaint?n.match(/data:image\/.*;base64,/i)?new i(n.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),!1):this.isSameOrigin(n)||this.options.allowTaint===!0||this.isSVG(n)?new i(n,!1):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new i(n,!0):this.options.proxy?new l(n,this.options.proxy):new t(n):new u(n)}return"linear-gradient"===e.method?new p(e):"gradient"===e.method?new c(e):"svg"===e.method?new a(e.args[0],this.support.svg):"IFRAME"===e.method?new s(e.args[0],this.isSameOrigin(e.args[0].src),this.options):new t(e)},f.prototype.isSVG=function(e){return"svg"===e.substring(e.length-3).toLowerCase()||u.prototype.isInline(e)},f.prototype.imageExists=function(e,n){return e.some(function(e){return e.src===n})},f.prototype.isSameOrigin=function(e){return this.getOrigin(e)===this.origin},f.prototype.getOrigin=function(e){var n=this.link||(this.link=document.createElement("a"));return n.href=e,n.href=n.href,n.protocol+n.hostname+n.port},f.prototype.getPromise=function(e){return this.timeout(e,this.options.imageTimeout)["catch"](function(){var n=new t(e.src);return n.promise.then(function(n){e.image=n})})},f.prototype.get=function(e){var n=null;return this.images.some(function(f){return(n=f).src===e})?n:null},f.prototype.fetch=function(e){return this.images=e.reduce(y(this.findBackgroundImage,this),this.findImages(e)),this.images.forEach(function(e,n){e.promise.then(function(){d("Succesfully loaded image #"+(n+1),e)},function(f){d("Failed loading image #"+(n+1),e,f)})}),this.ready=o.all(this.images.map(this.getPromise,this)),d("Finished searching images"),this},f.prototype.timeout=function(e,n){var f,i=o.race([e.promise,new o(function(o,i){f=setTimeout(function(){d("Timed out loading image",e),i(e)},n)})]).then(function(e){return clearTimeout(f),e});return i["catch"](function(){clearTimeout(f)}),i},n.exports=f},{"./dummyimagecontainer":7,"./framecontainer":10,"./imagecontainer":12,"./lineargradientcontainer":14,"./log":15,"./promise":18,"./proxyimagecontainer":20,"./svgcontainer":26,"./svgnodecontainer":27,"./utils":29,"./webkitgradientcontainer":30}],14:[function(e,n){function f(e){o.apply(this,arguments),this.type=this.TYPES.LINEAR;var n=null===e.args[0].match(this.stepRegExp);n?e.args[0].split(" ").reverse().forEach(function(e){switch(e){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0;break;case"to":var n=this.y0,f=this.x0;this.y0=this.y1,this.x0=this.x1,this.x1=f,this.y1=n}},this):(this.y0=0,this.y1=1),this.colorStops=e.args.slice(n?1:0).map(function(e){var n=e.match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)|\w+)\s*(\d{1,3})?(%|px)?/);return{color:new d(n[1]),stop:"%"===n[3]?n[2]/100:null}},this),null===this.colorStops[0].stop&&(this.colorStops[0].stop=0),null===this.colorStops[this.colorStops.length-1].stop&&(this.colorStops[this.colorStops.length-1].stop=1),this.colorStops.forEach(function(e,n){null===e.stop&&this.colorStops.slice(n).some(function(f,o){return null!==f.stop?(e.stop=(f.stop-this.colorStops[n-1].stop)/(o+1)+this.colorStops[n-1].stop,!0):!1},this)},this)}var o=e("./gradientcontainer"),d=e("./color");f.prototype=Object.create(o.prototype),f.prototype.stepRegExp=/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/,n.exports=f},{"./color":5,"./gradientcontainer":11}],15:[function(e,n){n.exports=function(){window.html2canvas.logging&&window.console&&window.console.log&&Function.prototype.bind.call(window.console.log,window.console).apply(window.console,[Date.now()-window.html2canvas.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))}},{}],16:[function(e,n){function f(e,n){this.node=e,this.parent=n,this.stack=null,this.bounds=null,this.borders=null,this.clip=[],this.backgroundClip=[],this.offsetBounds=null,this.visible=null,this.computedStyles=null,this.colors={},this.styles={},this.backgroundImages=null,this.transformData=null,this.transformMatrix=null,this.isPseudoElement=!1,this.opacity=null}function o(e){var n=e.options[e.selectedIndex||0];return n?n.text||"":""}function d(e){if(e&&"matrix"===e[1])return e[2].split(",").map(function(e){return parseFloat(e.trim())});if(e&&"matrix3d"===e[1]){var n=e[2].split(",").map(function(e){return parseFloat(e.trim())});return[n[0],n[1],n[4],n[5],n[12],n[13]]}}function i(e){return-1!==e.toString().indexOf("%")}function t(e){return e.replace("px","")}function l(e){return parseFloat(e)}var s=e("./color"),u=e("./utils"),a=u.getBounds,p=u.parseBackgrounds,c=u.offsetBounds;f.prototype.cloneTo=function(e){e.visible=this.visible,e.borders=this.borders,e.bounds=this.bounds,e.clip=this.clip,e.backgroundClip=this.backgroundClip,e.computedStyles=this.computedStyles,e.styles=this.styles,e.backgroundImages=this.backgroundImages,e.opacity=this.opacity},f.prototype.getOpacity=function(){return null===this.opacity?this.opacity=this.cssFloat("opacity"):this.opacity},f.prototype.assignStack=function(e){this.stack=e,e.children.push(this)},f.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")&&("INPUT"!==this.node.nodeName||"hidden"!==this.node.getAttribute("type"))},f.prototype.css=function(e){return this.computedStyles||(this.computedStyles=this.isPseudoElement?this.parent.computedStyle(this.before?":before":":after"):this.computedStyle(null)),this.styles[e]||(this.styles[e]=this.computedStyles[e])},f.prototype.prefixedCss=function(e){var n=["webkit","moz","ms","o"],f=this.css(e);return void 0===f&&n.some(function(n){return f=this.css(n+e.substr(0,1).toUpperCase()+e.substr(1)),void 0!==f},this),void 0===f?null:f},f.prototype.computedStyle=function(e){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,e)},f.prototype.cssInt=function(e){var n=parseInt(this.css(e),10);return isNaN(n)?0:n},f.prototype.color=function(e){return this.colors[e]||(this.colors[e]=new s(this.css(e)))},f.prototype.cssFloat=function(e){var n=parseFloat(this.css(e));return isNaN(n)?0:n},f.prototype.fontWeight=function(){var e=this.css("fontWeight");switch(parseInt(e,10)){case 401:e="bold";break;case 400:e="normal"}return e},f.prototype.parseClip=function(){var e=this.css("clip").match(this.CLIP);return e?{top:parseInt(e[1],10),right:parseInt(e[2],10),bottom:parseInt(e[3],10),left:parseInt(e[4],10)}:null},f.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=p(this.css("backgroundImage"))) +},f.prototype.cssList=function(e,n){var f=(this.css(e)||"").split(",");return f=f[n||0]||f[0]||"auto",f=f.trim().split(" "),1===f.length&&(f=[f[0],i(f[0])?"auto":f[0]]),f},f.prototype.parseBackgroundSize=function(e,n,f){var o,d,t=this.cssList("backgroundSize",f);if(i(t[0]))o=e.width*parseFloat(t[0])/100;else{if(/contain|cover/.test(t[0])){var l=e.width/e.height,s=n.width/n.height;return s>l^"contain"===t[0]?{width:e.height*s,height:e.height}:{width:e.width,height:e.width/s}}o=parseInt(t[0],10)}return d="auto"===t[0]&&"auto"===t[1]?n.height:"auto"===t[1]?o/n.width*n.height:i(t[1])?e.height*parseFloat(t[1])/100:parseInt(t[1],10),"auto"===t[0]&&(o=d/n.height*n.width),{width:o,height:d}},f.prototype.parseBackgroundPosition=function(e,n,f,o){var d,t,l=this.cssList("backgroundPosition",f);return d=i(l[0])?(e.width-(o||n).width)*(parseFloat(l[0])/100):parseInt(l[0],10),t="auto"===l[1]?d/n.width*n.height:i(l[1])?(e.height-(o||n).height)*parseFloat(l[1])/100:parseInt(l[1],10),"auto"===l[0]&&(d=t/n.height*n.width),{left:d,top:t}},f.prototype.parseBackgroundRepeat=function(e){return this.cssList("backgroundRepeat",e)[0]},f.prototype.parseTextShadows=function(){var e=this.css("textShadow"),n=[];if(e&&"none"!==e)for(var f=e.match(this.TEXT_SHADOW_PROPERTY),o=0;f&&o0?(this.renderIndex=0,this.asyncRenderer(this.renderQueue,e)):e():(this.renderQueue.forEach(this.paint,this),e())},this))},this))}function o(e){return e.parent&&e.parent.clip.length}function d(e){return e.replace(/(\-[a-z])/g,function(e){return e.toUpperCase().replace("-","")})}function i(){}function t(e,n,f,o){return e.map(function(d,i){if(d.width>0){var t=n.left,l=n.top,s=n.width,u=n.height-e[2].width;switch(i){case 0:u=e[0].width,d.args=a({c1:[t,l],c2:[t+s,l],c3:[t+s-e[1].width,l+u],c4:[t+e[3].width,l+u]},o[0],o[1],f.topLeftOuter,f.topLeftInner,f.topRightOuter,f.topRightInner);break;case 1:t=n.left+n.width-e[1].width,s=e[1].width,d.args=a({c1:[t+s,l],c2:[t+s,l+u+e[2].width],c3:[t,l+u],c4:[t,l+e[0].width]},o[1],o[2],f.topRightOuter,f.topRightInner,f.bottomRightOuter,f.bottomRightInner);break;case 2:l=l+n.height-e[2].width,u=e[2].width,d.args=a({c1:[t+s,l+u],c2:[t,l+u],c3:[t+e[3].width,l],c4:[t+s-e[3].width,l]},o[2],o[3],f.bottomRightOuter,f.bottomRightInner,f.bottomLeftOuter,f.bottomLeftInner);break;case 3:s=e[3].width,d.args=a({c1:[t,l+u+e[2].width],c2:[t,l],c3:[t+s,l+e[0].width],c4:[t+s,l+u]},o[3],o[0],f.bottomLeftOuter,f.bottomLeftInner,f.topLeftOuter,f.topLeftInner)}}return d})}function l(e,n,f,o){var d=4*((Math.sqrt(2)-1)/3),i=f*d,t=o*d,l=e+f,s=n+o;return{topLeft:u({x:e,y:s},{x:e,y:s-t},{x:l-i,y:n},{x:l,y:n}),topRight:u({x:e,y:n},{x:e+i,y:n},{x:l,y:s-t},{x:l,y:s}),bottomRight:u({x:l,y:n},{x:l,y:n+t},{x:e+i,y:s},{x:e,y:s}),bottomLeft:u({x:l,y:s},{x:l-i,y:s},{x:e,y:n+t},{x:e,y:n})}}function s(e,n,f){var o=e.left,d=e.top,i=e.width,t=e.height,s=n[0][0],u=n[0][1],a=n[1][0],p=n[1][1],c=n[2][0],y=n[2][1],m=n[3][0],r=n[3][1],v=i-a,w=t-y,b=i-c,g=t-r;return{topLeftOuter:l(o,d,s,u).topLeft.subdivide(.5),topLeftInner:l(o+f[3].width,d+f[0].width,Math.max(0,s-f[3].width),Math.max(0,u-f[0].width)).topLeft.subdivide(.5),topRightOuter:l(o+v,d,a,p).topRight.subdivide(.5),topRightInner:l(o+Math.min(v,i+f[3].width),d+f[0].width,v>i+f[3].width?0:a-f[3].width,p-f[0].width).topRight.subdivide(.5),bottomRightOuter:l(o+b,d+w,c,y).bottomRight.subdivide(.5),bottomRightInner:l(o+Math.min(b,i-f[3].width),d+Math.min(w,t+f[0].width),Math.max(0,c-f[1].width),y-f[2].width).bottomRight.subdivide(.5),bottomLeftOuter:l(o,d+g,m,r).bottomLeft.subdivide(.5),bottomLeftInner:l(o+f[3].width,d+g,Math.max(0,m-f[3].width),r-f[2].width).bottomLeft.subdivide(.5)}}function u(e,n,f,o){var d=function(e,n,f){return{x:e.x+(n.x-e.x)*f,y:e.y+(n.y-e.y)*f}};return{start:e,startControl:n,endControl:f,end:o,subdivide:function(i){var t=d(e,n,i),l=d(n,f,i),s=d(f,o,i),a=d(t,l,i),p=d(l,s,i),c=d(a,p,i);return[u(e,t,a,c),u(c,p,s,o)]},curveTo:function(e){e.push(["bezierCurve",n.x,n.y,f.x,f.y,o.x,o.y])},curveToReversed:function(o){o.push(["bezierCurve",f.x,f.y,n.x,n.y,e.x,e.y])}}}function a(e,n,f,o,d,i,t){var l=[];return n[0]>0||n[1]>0?(l.push(["line",o[1].start.x,o[1].start.y]),o[1].curveTo(l)):l.push(["line",e.c1[0],e.c1[1]]),f[0]>0||f[1]>0?(l.push(["line",i[0].start.x,i[0].start.y]),i[0].curveTo(l),l.push(["line",t[0].end.x,t[0].end.y]),t[0].curveToReversed(l)):(l.push(["line",e.c2[0],e.c2[1]]),l.push(["line",e.c3[0],e.c3[1]])),n[0]>0||n[1]>0?(l.push(["line",d[1].end.x,d[1].end.y]),d[1].curveToReversed(l)):l.push(["line",e.c4[0],e.c4[1]]),l}function p(e,n,f,o,d,i,t){n[0]>0||n[1]>0?(e.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(e),o[1].curveTo(e)):e.push(["line",i,t]),(f[0]>0||f[1]>0)&&e.push(["line",d[0].start.x,d[0].start.y])}function c(e){return e.cssInt("zIndex")<0}function y(e){return e.cssInt("zIndex")>0}function m(e){return 0===e.cssInt("zIndex")}function r(e){return-1!==["inline","inline-block","inline-table"].indexOf(e.css("display"))}function v(e){return e instanceof V}function w(e){return e.node.data.trim().length>0}function b(e){return/^(normal|none|0px)$/.test(e.parent.css("letterSpacing"))}function g(e){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(n){var f=e.css("border"+n+"Radius"),o=f.split(" ");return o.length<=1&&(o[1]=o[0]),o.map(F)})}function h(e){return e.nodeType===Node.TEXT_NODE||e.nodeType===Node.ELEMENT_NODE}function x(e){var n=e.css("position"),f=-1!==["absolute","relative","fixed"].indexOf(n)?e.css("zIndex"):"auto";return"auto"!==f}function j(e){return"static"!==e.css("position")}function k(e){return"none"!==e.css("float")}function q(e){return-1!==["inline-block","inline-table"].indexOf(e.css("display"))}function z(e){var n=this;return function(){return!e.apply(n,arguments)}}function A(e){return e.node.nodeType===Node.ELEMENT_NODE}function B(e){return e.isPseudoElement===!0}function C(e){return e.node.nodeType===Node.TEXT_NODE}function D(e){return function(n,f){return n.cssInt("zIndex")+e.indexOf(n)/e.length-(f.cssInt("zIndex")+e.indexOf(f)/e.length)}}function E(e){return e.getOpacity()<1}function F(e){return parseInt(e,10)}function G(e){return e.width}function H(e){return e.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR","OPTION"].indexOf(e.node.nodeName)}function I(e){return[].concat.apply([],e)}function J(e){var n=e.substr(0,1);return n===e.substr(e.length-1)&&n.match(/'|"/)?e.substr(1,e.length-2):e}function K(e){for(var n,f=[],o=0,d=!1;e.length;)L(e[o])===d?(n=e.splice(0,o),n.length&&f.push(O.ucs2.encode(n)),d=!d,o=0):o++,o>=e.length&&(n=e.splice(0,o),n.length&&f.push(O.ucs2.encode(n)));return f}function L(e){return-1!==[32,13,10,9,45].indexOf(e)}function M(e){return/[^\u0000-\u00ff]/.test(e)}var N=e("./log"),O=e("punycode"),P=e("./nodecontainer"),Q=e("./textcontainer"),R=e("./pseudoelementcontainer"),S=e("./fontmetrics"),T=e("./color"),U=e("./promise"),V=e("./stackingcontext"),W=e("./utils"),X=W.bind,Y=W.getBounds,Z=W.parseBackgrounds,$=W.offsetBounds;f.prototype.calculateOverflowClips=function(){this.nodes.forEach(function(e){if(A(e)){B(e)&&e.appendToDOM(),e.borders=this.parseBorders(e);var n="hidden"===e.css("overflow")?[e.borders.clip]:[],f=e.parseClip();f&&-1!==["absolute","fixed"].indexOf(e.css("position"))&&n.push([["rect",e.bounds.left+f.left,e.bounds.top+f.top,f.right-f.left,f.bottom-f.top]]),e.clip=o(e)?e.parent.clip.concat(n):n,e.backgroundClip="hidden"!==e.css("overflow")?e.clip.concat([e.borders.clip]):e.clip,B(e)&&e.cleanDOM()}else C(e)&&(e.clip=o(e)?e.parent.clip:[]);B(e)||(e.bounds=null)},this)},f.prototype.asyncRenderer=function(e,n,f){f=f||Date.now(),this.paint(e[this.renderIndex++]),e.length===this.renderIndex?n():f+20>Date.now()?this.asyncRenderer(e,n,f):setTimeout(X(function(){this.asyncRenderer(e,n)},this),0)},f.prototype.createPseudoHideStyles=function(e){this.createStyles(e,"."+R.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+':before { content: "" !important; display: none !important; }.'+R.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER+':after { content: "" !important; display: none !important; }')},f.prototype.disableAnimations=function(e){this.createStyles(e,"* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}")},f.prototype.createStyles=function(e,n){var f=e.createElement("style");f.innerHTML=n,e.body.appendChild(f)},f.prototype.getPseudoElements=function(e){var n=[[e]];if(e.node.nodeType===Node.ELEMENT_NODE){var f=this.getPseudoElement(e,":before"),o=this.getPseudoElement(e,":after");f&&n.push(f),o&&n.push(o)}return I(n)},f.prototype.getPseudoElement=function(e,n){var f=e.computedStyle(n);if(!f||!f.content||"none"===f.content||"-moz-alt-content"===f.content||"none"===f.display)return null;for(var o=J(f.content),i="url"===o.substr(0,3),t=document.createElement(i?"img":"html2canvaspseudoelement"),l=new R(t,e,n),s=f.length-1;s>=0;s--){var u=d(f.item(s));t.style[u]=f[u]}if(t.className=R.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+" "+R.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER,i)return t.src=Z(o)[0].args[0],[l];var a=document.createTextNode(o);return t.appendChild(a),[l,new Q(a,l)]},f.prototype.getChildren=function(e){return I([].filter.call(e.node.childNodes,h).map(function(n){var f=[n.nodeType===Node.TEXT_NODE?new Q(n,e):new P(n,e)].filter(H);return n.nodeType===Node.ELEMENT_NODE&&f.length&&"TEXTAREA"!==n.tagName?f[0].isElementVisible()?f.concat(this.getChildren(f[0])):[]:f},this))},f.prototype.newStackingContext=function(e,n){var f=new V(n,e.getOpacity(),e.node,e.parent);e.cloneTo(f);var o=n?f.getParentStack(this):f.parent.stack;o.contexts.push(f),e.stack=f},f.prototype.createStackingContexts=function(){this.nodes.forEach(function(e){A(e)&&(this.isRootElement(e)||E(e)||x(e)||this.isBodyWithTransparentRoot(e)||e.hasTransform())?this.newStackingContext(e,!0):A(e)&&(j(e)&&m(e)||q(e)||k(e))?this.newStackingContext(e,!1):e.assignStack(e.parent.stack)},this)},f.prototype.isBodyWithTransparentRoot=function(e){return"BODY"===e.node.nodeName&&e.parent.color("backgroundColor").isTransparent()},f.prototype.isRootElement=function(e){return null===e.parent},f.prototype.sortStackingContexts=function(e){e.contexts.sort(D(e.contexts.slice(0))),e.contexts.forEach(this.sortStackingContexts,this)},f.prototype.parseTextBounds=function(e){return function(n,f,o){if("none"!==e.parent.css("textDecoration").substr(0,4)||0!==n.trim().length){if(this.support.rangeBounds&&!e.parent.hasTransform()){var d=o.slice(0,f).join("").length;return this.getRangeBounds(e.node,d,n.length)}if(e.node&&"string"==typeof e.node.data){var i=e.node.splitText(n.length),t=this.getWrapperBounds(e.node,e.parent.hasTransform());return e.node=i,t}}else(!this.support.rangeBounds||e.parent.hasTransform())&&(e.node=e.node.splitText(n.length));return{}}},f.prototype.getWrapperBounds=function(e,n){var f=e.ownerDocument.createElement("html2canvaswrapper"),o=e.parentNode,d=e.cloneNode(!0);f.appendChild(e.cloneNode(!0)),o.replaceChild(f,e);var i=n?$(f):Y(f);return o.replaceChild(d,f),i},f.prototype.getRangeBounds=function(e,n,f){var o=this.range||(this.range=e.ownerDocument.createRange());return o.setStart(e,n),o.setEnd(e,n+f),o.getBoundingClientRect()},f.prototype.parse=function(e){var n=e.contexts.filter(c),f=e.children.filter(A),o=f.filter(z(k)),d=o.filter(z(j)).filter(z(r)),t=f.filter(z(j)).filter(k),l=o.filter(z(j)).filter(r),s=e.contexts.concat(o.filter(j)).filter(m),u=e.children.filter(C).filter(w),a=e.contexts.filter(y);n.concat(d).concat(t).concat(l).concat(s).concat(u).concat(a).forEach(function(e){this.renderQueue.push(e),v(e)&&(this.parse(e),this.renderQueue.push(new i))},this)},f.prototype.paint=function(e){try{e instanceof i?this.renderer.ctx.restore():C(e)?(B(e.parent)&&e.parent.appendToDOM(),this.paintText(e),B(e.parent)&&e.parent.cleanDOM()):this.paintNode(e)}catch(n){if(N(n),this.options.strict)throw n}},f.prototype.paintNode=function(e){v(e)&&(this.renderer.setOpacity(e.opacity),this.renderer.ctx.save(),e.hasTransform()&&this.renderer.setTransform(e.parseTransform())),"INPUT"===e.node.nodeName&&"checkbox"===e.node.type?this.paintCheckbox(e):"INPUT"===e.node.nodeName&&"radio"===e.node.type?this.paintRadio(e):this.paintElement(e)},f.prototype.paintElement=function(e){var n=e.parseBounds();this.renderer.clip(e.backgroundClip,function(){this.renderer.renderBackground(e,n,e.borders.borders.map(G))},this),this.renderer.clip(e.clip,function(){this.renderer.renderBorders(e.borders.borders)},this),this.renderer.clip(e.backgroundClip,function(){switch(e.node.nodeName){case"svg":case"IFRAME":var f=this.images.get(e.node);f?this.renderer.renderImage(e,n,e.borders,f):N("Error loading <"+e.node.nodeName+">",e.node);break;case"IMG":var o=this.images.get(e.node.src);o?this.renderer.renderImage(e,n,e.borders,o):N("Error loading ",e.node.src);break;case"CANVAS":this.renderer.renderImage(e,n,e.borders,{image:e.node});break;case"SELECT":case"INPUT":case"TEXTAREA":this.paintFormValue(e)}},this)},f.prototype.paintCheckbox=function(e){var n=e.parseBounds(),f=Math.min(n.width,n.height),o={width:f-1,height:f-1,top:n.top,left:n.left},d=[3,3],i=[d,d,d,d],l=[1,1,1,1].map(function(e){return{color:new T("#A5A5A5"),width:e}}),u=s(o,i,l);this.renderer.clip(e.backgroundClip,function(){this.renderer.rectangle(o.left+1,o.top+1,o.width-2,o.height-2,new T("#DEDEDE")),this.renderer.renderBorders(t(l,o,u,i)),e.node.checked&&(this.renderer.font(new T("#424242"),"normal","normal","bold",f-3+"px","arial"),this.renderer.text("✔",o.left+f/6,o.top+f-1))},this)},f.prototype.paintRadio=function(e){var n=e.parseBounds(),f=Math.min(n.width,n.height)-2;this.renderer.clip(e.backgroundClip,function(){this.renderer.circleStroke(n.left+1,n.top+1,f,new T("#DEDEDE"),1,new T("#A5A5A5")),e.node.checked&&this.renderer.circle(Math.ceil(n.left+f/4)+1,Math.ceil(n.top+f/4)+1,Math.floor(f/2),new T("#424242"))},this)},f.prototype.paintFormValue=function(e){var n=e.getValue();if(n.length>0){var f=e.node.ownerDocument,o=f.createElement("html2canvaswrapper"),d=["lineHeight","textAlign","fontFamily","fontWeight","fontSize","color","paddingLeft","paddingTop","paddingRight","paddingBottom","width","height","borderLeftStyle","borderTopStyle","borderLeftWidth","borderTopWidth","boxSizing","whiteSpace","wordWrap"];d.forEach(function(n){try{o.style[n]=e.css(n)}catch(f){N("html2canvas: Parse: Exception caught in renderFormValue: "+f.message)}});var i=e.parseBounds();o.style.position="fixed",o.style.left=i.left+"px",o.style.top=i.top+"px",o.textContent=n,f.body.appendChild(o),this.paintText(new Q(o.firstChild,e)),f.body.removeChild(o)}},f.prototype.paintText=function(e){e.applyTextTransform();var n=O.ucs2.decode(e.node.data),f=this.options.letterRendering&&!b(e)||M(e.node.data)?n.map(function(e){return O.ucs2.encode([e])}):K(n),o=e.parent.fontWeight(),d=e.parent.css("fontSize"),i=e.parent.css("fontFamily"),t=e.parent.parseTextShadows();this.renderer.font(e.parent.color("color"),e.parent.css("fontStyle"),e.parent.css("fontVariant"),o,d,i),t.length?this.renderer.fontShadow(t[0].color,t[0].offsetX,t[0].offsetY,t[0].blur):this.renderer.clearShadow(),this.renderer.clip(e.parent.clip,function(){f.map(this.parseTextBounds(e),this).forEach(function(n,o){n&&(this.renderer.text(f[o],n.left,n.bottom),this.renderTextDecoration(e.parent,n,this.fontMetrics.getMetrics(i,d)))},this)},this)},f.prototype.renderTextDecoration=function(e,n,f){switch(e.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(n.left,Math.round(n.top+f.baseline+f.lineWidth),n.width,1,e.color("color"));break;case"overline":this.renderer.rectangle(n.left,Math.round(n.top),n.width,1,e.color("color"));break;case"line-through":this.renderer.rectangle(n.left,Math.ceil(n.top+f.middle+f.lineWidth),n.width,1,e.color("color"))}};var _={inset:[["darken",.6],["darken",.1],["darken",.1],["darken",.6]]};f.prototype.parseBorders=function(e){var n=e.parseBounds(),f=g(e),o=["Top","Right","Bottom","Left"].map(function(n,f){var o=e.css("border"+n+"Style"),d=e.color("border"+n+"Color");"inset"===o&&d.isBlack()&&(d=new T([255,255,255,d.a]));var i=_[o]?_[o][f]:null;return{width:e.cssInt("border"+n+"Width"),color:i?d[i[0]](i[1]):d,args:null}}),d=s(n,f,o);return{clip:this.parseBackgroundClip(e,d,o,f,n),borders:t(o,n,d,f)}},f.prototype.parseBackgroundClip=function(e,n,f,o,d){var i=e.css("backgroundClip"),t=[];switch(i){case"content-box":case"padding-box":p(t,o[0],o[1],n.topLeftInner,n.topRightInner,d.left+f[3].width,d.top+f[0].width),p(t,o[1],o[2],n.topRightInner,n.bottomRightInner,d.left+d.width-f[1].width,d.top+f[0].width),p(t,o[2],o[3],n.bottomRightInner,n.bottomLeftInner,d.left+d.width-f[1].width,d.top+d.height-f[2].width),p(t,o[3],o[0],n.bottomLeftInner,n.topLeftInner,d.left+f[3].width,d.top+d.height-f[2].width);break;default:p(t,o[0],o[1],n.topLeftOuter,n.topRightOuter,d.left,d.top),p(t,o[1],o[2],n.topRightOuter,n.bottomRightOuter,d.left+d.width,d.top),p(t,o[2],o[3],n.bottomRightOuter,n.bottomLeftOuter,d.left+d.width,d.top+d.height),p(t,o[3],o[0],n.bottomLeftOuter,n.topLeftOuter,d.left,d.top+d.height)}return t},n.exports=f},{"./color":5,"./fontmetrics":9,"./log":15,"./nodecontainer":16,"./promise":18,"./pseudoelementcontainer":21,"./stackingcontext":24,"./textcontainer":28,"./utils":29,punycode:3}],18:[function(e,n){n.exports=e("es6-promise").Promise},{"es6-promise":1}],19:[function(e,n,f){function o(e,n,f){var o="withCredentials"in new XMLHttpRequest;if(!n)return a.reject("No proxy configured");var d=t(o),s=l(n,e,d);return o?p(s):i(f,s,d).then(function(e){return r(e.content)})}function d(e,n,f){var o="crossOrigin"in new Image,d=t(o),s=l(n,e,d);return o?a.resolve(s):i(f,s,d).then(function(e){return"data:"+e.type+";base64,"+e.content})}function i(e,n,f){return new a(function(o,d){var i=e.createElement("script"),t=function(){delete window.html2canvas.proxy[f],e.body.removeChild(i)};window.html2canvas.proxy[f]=function(e){t(),o(e)},i.src=n,i.onerror=function(e){t(),d(e)},e.body.appendChild(i)})}function t(e){return e?"":"html2canvas_"+Date.now()+"_"+ ++v+"_"+Math.round(1e5*Math.random())}function l(e,n,f){return e+"?url="+encodeURIComponent(n)+(f.length?"&callback=html2canvas.proxy."+f:"")}function s(e){return function(n){var f,o=new DOMParser;try{f=o.parseFromString(n,"text/html")}catch(d){y("DOMParser not supported, falling back to createHTMLDocument"),f=document.implementation.createHTMLDocument("");try{f.open(),f.write(n),f.close()}catch(i){y("createHTMLDocument write not supported, falling back to document.body.innerHTML"),f.body.innerHTML=n}}var t=f.querySelector("base");if(!t||!t.href.host){var l=f.createElement("base");l.href=e,f.head.insertBefore(l,f.head.firstChild)}return f}}function u(e,n,f,d,i,t){return new o(e,n,window.document).then(s(e)).then(function(e){return m(e,f,d,i,t,0,0)})}var a=e("./promise"),p=e("./xhr"),c=e("./utils"),y=e("./log"),m=e("./clone"),r=c.decode64,v=0;f.Proxy=o,f.ProxyURL=d,f.loadUrlDocument=u},{"./clone":4,"./log":15,"./promise":18,"./utils":29,"./xhr":31}],20:[function(e,n){function f(e,n){var f=document.createElement("a");f.href=e,e=f.href,this.src=e,this.image=new Image;var i=this;this.promise=new d(function(f,d){i.image.crossOrigin="Anonymous",i.image.onload=f,i.image.onerror=d,new o(e,n,document).then(function(e){i.image.src=e})["catch"](d)})}var o=e("./proxy").ProxyURL,d=e("./promise");n.exports=f},{"./promise":18,"./proxy":19}],21:[function(e,n){function f(e,n,f){o.call(this,e,n),this.isPseudoElement=!0,this.before=":before"===f}var o=e("./nodecontainer");f.prototype.cloneTo=function(e){f.prototype.cloneTo.call(this,e),e.isPseudoElement=!0,e.before=this.before},f.prototype=Object.create(o.prototype),f.prototype.appendToDOM=function(){this.before?this.parent.node.insertBefore(this.node,this.parent.node.firstChild):this.parent.node.appendChild(this.node),this.parent.node.className+=" "+this.getHideClass()},f.prototype.cleanDOM=function(){this.node.parentNode.removeChild(this.node),this.parent.node.className=this.parent.node.className.replace(this.getHideClass(),"")},f.prototype.getHideClass=function(){return this["PSEUDO_HIDE_ELEMENT_CLASS_"+(this.before?"BEFORE":"AFTER")]},f.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE="___html2canvas___pseudoelement_before",f.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER="___html2canvas___pseudoelement_after",n.exports=f},{"./nodecontainer":16}],22:[function(e,n){function f(e,n,f,o,d){this.width=e,this.height=n,this.images=f,this.options=o,this.document=d}var o=e("./log");f.prototype.renderImage=function(e,n,f,o){var d=e.cssInt("paddingLeft"),i=e.cssInt("paddingTop"),t=e.cssInt("paddingRight"),l=e.cssInt("paddingBottom"),s=f.borders,u=n.width-(s[1].width+s[3].width+d+t),a=n.height-(s[0].width+s[2].width+i+l);this.drawImage(o,0,0,o.image.width||u,o.image.height||a,n.left+d+s[3].width,n.top+i+s[0].width,u,a)},f.prototype.renderBackground=function(e,n,f){n.height>0&&n.width>0&&(this.renderBackgroundColor(e,n),this.renderBackgroundImage(e,n,f))},f.prototype.renderBackgroundColor=function(e,n){var f=e.color("backgroundColor");f.isTransparent()||this.rectangle(n.left,n.top,n.width,n.height,f)},f.prototype.renderBorders=function(e){e.forEach(this.renderBorder,this)},f.prototype.renderBorder=function(e){e.color.isTransparent()||null===e.args||this.drawShape(e.args,e.color)},f.prototype.renderBackgroundImage=function(e,n,f){var d=e.parseBackgroundImages();d.reverse().forEach(function(d,i,t){switch(d.method){case"url":var l=this.images.get(d.args[0]);l?this.renderBackgroundRepeating(e,n,l,t.length-(i+1),f):o("Error loading background-image",d.args[0]);break;case"linear-gradient":case"gradient":var s=this.images.get(d.value);s?this.renderBackgroundGradient(s,n,f):o("Error loading background-image",d.args[0]);break;case"none":break;default:o("Unknown background-image type",d.args[0])}},this)},f.prototype.renderBackgroundRepeating=function(e,n,f,o,d){var i=e.parseBackgroundSize(n,f.image,o),t=e.parseBackgroundPosition(n,f.image,o,i),l=e.parseBackgroundRepeat(o);switch(l){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(f,t,i,n,n.left+d[3],n.top+t.top+d[0],99999,i.height,d);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(f,t,i,n,n.left+t.left+d[3],n.top+d[0],i.width,99999,d);break;case"no-repeat":this.backgroundRepeatShape(f,t,i,n,n.left+t.left+d[3],n.top+t.top+d[0],i.width,i.height,d);break;default:this.renderBackgroundRepeat(f,t,i,{top:n.top,left:n.left},d[3],d[0])}},n.exports=f},{"./log":15}],23:[function(e,n){function f(e,n){d.apply(this,arguments),this.canvas=this.options.canvas||this.document.createElement("canvas"),this.options.canvas||(this.canvas.width=e,this.canvas.height=n),this.ctx=this.canvas.getContext("2d"),this.taintCtx=this.document.createElement("canvas").getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},t("Initialized CanvasRenderer with size",e,"x",n)}function o(e){return e.length>0}var d=e("../renderer"),i=e("../lineargradientcontainer"),t=e("../log");f.prototype=Object.create(d.prototype),f.prototype.setFillStyle=function(e){return this.ctx.fillStyle="object"==typeof e&&e.isColor?e.toString():e,this.ctx},f.prototype.rectangle=function(e,n,f,o,d){this.setFillStyle(d).fillRect(e,n,f,o)},f.prototype.circle=function(e,n,f,o){this.setFillStyle(o),this.ctx.beginPath(),this.ctx.arc(e+f/2,n+f/2,f/2,0,2*Math.PI,!0),this.ctx.closePath(),this.ctx.fill()},f.prototype.circleStroke=function(e,n,f,o,d,i){this.circle(e,n,f,o),this.ctx.strokeStyle=i.toString(),this.ctx.stroke()},f.prototype.drawShape=function(e,n){this.shape(e),this.setFillStyle(n).fill()},f.prototype.taints=function(e){if(null===e.tainted){this.taintCtx.drawImage(e.image,0,0);try{this.taintCtx.getImageData(0,0,1,1),e.tainted=!1}catch(n){this.taintCtx=document.createElement("canvas").getContext("2d"),e.tainted=!0}}return e.tainted},f.prototype.drawImage=function(e,n,f,o,d,i,t,l,s){(!this.taints(e)||this.options.allowTaint)&&this.ctx.drawImage(e.image,n,f,o,d,i,t,l,s)},f.prototype.clip=function(e,n,f){this.ctx.save(),e.filter(o).forEach(function(e){this.shape(e).clip()},this),n.call(f),this.ctx.restore()},f.prototype.shape=function(e){return this.ctx.beginPath(),e.forEach(function(e,n){"rect"===e[0]?this.ctx.rect.apply(this.ctx,e.slice(1)):this.ctx[0===n?"moveTo":e[0]+"To"].apply(this.ctx,e.slice(1))},this),this.ctx.closePath(),this.ctx},f.prototype.font=function(e,n,f,o,d,i){this.setFillStyle(e).font=[n,f,o,d,i].join(" ").split(",")[0]},f.prototype.fontShadow=function(e,n,f,o){this.setVariable("shadowColor",e.toString()).setVariable("shadowOffsetY",n).setVariable("shadowOffsetX",f).setVariable("shadowBlur",o)},f.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},f.prototype.setOpacity=function(e){this.ctx.globalAlpha=e},f.prototype.setTransform=function(e){this.ctx.translate(e.origin[0],e.origin[1]),this.ctx.transform.apply(this.ctx,e.matrix),this.ctx.translate(-e.origin[0],-e.origin[1])},f.prototype.setVariable=function(e,n){return this.variables[e]!==n&&(this.variables[e]=this.ctx[e]=n),this},f.prototype.text=function(e,n,f){this.ctx.fillText(e,n,f)},f.prototype.backgroundRepeatShape=function(e,n,f,o,d,i,t,l,s){var u=[["line",Math.round(d),Math.round(i)],["line",Math.round(d+t),Math.round(i)],["line",Math.round(d+t),Math.round(l+i)],["line",Math.round(d),Math.round(l+i)]];this.clip([u],function(){this.renderBackgroundRepeat(e,n,f,o,s[3],s[0])},this)},f.prototype.renderBackgroundRepeat=function(e,n,f,o,d,i){var t=Math.round(o.left+n.left+d),l=Math.round(o.top+n.top+i);this.setFillStyle(this.ctx.createPattern(this.resizeImage(e,f),"repeat")),this.ctx.translate(t,l),this.ctx.fill(),this.ctx.translate(-t,-l)},f.prototype.renderBackgroundGradient=function(e,n){if(e instanceof i){var f=this.ctx.createLinearGradient(n.left+n.width*e.x0,n.top+n.height*e.y0,n.left+n.width*e.x1,n.top+n.height*e.y1);e.colorStops.forEach(function(e){f.addColorStop(e.stop,e.color.toString())}),this.rectangle(n.left,n.top,n.width,n.height,f)}},f.prototype.resizeImage=function(e,n){var f=e.image;if(f.width===n.width&&f.height===n.height)return f;var o,d=document.createElement("canvas");return d.width=n.width,d.height=n.height,o=d.getContext("2d"),o.drawImage(f,0,0,f.width,f.height,0,0,n.width,n.height),d},n.exports=f},{"../lineargradientcontainer":14,"../log":15,"../renderer":22}],24:[function(e,n){function f(e,n,f,d){o.call(this,f,d),this.ownStacking=e,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*n}var o=e("./nodecontainer");f.prototype=Object.create(o.prototype),f.prototype.getParentStack=function(e){var n=this.parent?this.parent.stack:null;return n?n.ownStacking?n:n.getParentStack(e):e.stack},n.exports=f},{"./nodecontainer":16}],25:[function(e,n){function f(e){this.rangeBounds=this.testRangeBounds(e),this.cors=this.testCORS(),this.svg=this.testSVG()}f.prototype.testRangeBounds=function(e){var n,f,o,d,i=!1;return e.createRange&&(n=e.createRange(),n.getBoundingClientRect&&(f=e.createElement("boundtest"),f.style.height="123px",f.style.display="block",e.body.appendChild(f),n.selectNode(f),o=n.getBoundingClientRect(),d=o.height,123===d&&(i=!0),e.body.removeChild(f))),i},f.prototype.testCORS=function(){return"undefined"!=typeof(new Image).crossOrigin},f.prototype.testSVG=function(){var e=new Image,n=document.createElement("canvas"),f=n.getContext("2d");e.src="data:image/svg+xml,";try{f.drawImage(e,0,0),n.toDataURL()}catch(o){return!1}return!0},n.exports=f},{}],26:[function(e,n){function f(e){this.src=e,this.image=null;var n=this;this.promise=this.hasFabric().then(function(){return n.isInline(e)?o.resolve(n.inlineFormatting(e)):d(e)}).then(function(e){return new o(function(f){window.html2canvas.svg.fabric.loadSVGFromString(e,n.createCanvas.call(n,f))})})}var o=e("./promise"),d=e("./xhr"),i=e("./utils").decode64;f.prototype.hasFabric=function(){return window.html2canvas.svg&&window.html2canvas.svg.fabric?o.resolve():o.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"))},f.prototype.inlineFormatting=function(e){return/^data:image\/svg\+xml;base64,/.test(e)?this.decode64(this.removeContentType(e)):this.removeContentType(e)},f.prototype.removeContentType=function(e){return e.replace(/^data:image\/svg\+xml(;base64)?,/,"")},f.prototype.isInline=function(e){return/^data:image\/svg\+xml/i.test(e)},f.prototype.createCanvas=function(e){var n=this;return function(f,o){var d=new window.html2canvas.svg.fabric.StaticCanvas("c");n.image=d.lowerCanvasEl,d.setWidth(o.width).setHeight(o.height).add(window.html2canvas.svg.fabric.util.groupSVGElements(f,o)).renderAll(),e(d.lowerCanvasEl)}},f.prototype.decode64=function(e){return"function"==typeof window.atob?window.atob(e):i(e)},n.exports=f},{"./promise":18,"./utils":29,"./xhr":31}],27:[function(e,n){function f(e,n){this.src=e,this.image=null;var f=this;this.promise=n?new d(function(n,o){f.image=new Image,f.image.onload=n,f.image.onerror=o,f.image.src="data:image/svg+xml,"+(new XMLSerializer).serializeToString(e),f.image.complete===!0&&n(f.image) +}):this.hasFabric().then(function(){return new d(function(n){window.html2canvas.svg.fabric.parseSVGDocument(e,f.createCanvas.call(f,n))})})}var o=e("./svgcontainer"),d=e("./promise");f.prototype=Object.create(o.prototype),n.exports=f},{"./promise":18,"./svgcontainer":26}],28:[function(e,n){function f(e,n){d.call(this,e,n)}function o(e,n,f){return e.length>0?n+f.toUpperCase():void 0}var d=e("./nodecontainer");f.prototype=Object.create(d.prototype),f.prototype.applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},f.prototype.transform=function(e){var n=this.node.data;switch(e){case"lowercase":return n.toLowerCase();case"capitalize":return n.replace(/(^|\s|:|-|\(|\))([a-z])/g,o);case"uppercase":return n.toUpperCase();default:return n}},n.exports=f},{"./nodecontainer":16}],29:[function(e,n,f){f.smallImage=function(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},f.bind=function(e,n){return function(){return e.apply(n,arguments)}},f.decode64=function(e){var n,f,o,d,i,t,l,s,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=e.length,p="";for(n=0;a>n;n+=4)f=u.indexOf(e[n]),o=u.indexOf(e[n+1]),d=u.indexOf(e[n+2]),i=u.indexOf(e[n+3]),t=f<<2|o>>4,l=(15&o)<<4|d>>2,s=(3&d)<<6|i,p+=64===d?String.fromCharCode(t):64===i||-1===i?String.fromCharCode(t,l):String.fromCharCode(t,l,s);return p},f.getBounds=function(e){if(e.getBoundingClientRect){var n=e.getBoundingClientRect(),f=null==e.offsetWidth?n.width:e.offsetWidth;return{top:n.top,bottom:n.bottom||n.top+n.height,right:n.left+f,left:n.left,width:f,height:null==e.offsetHeight?n.height:e.offsetHeight}}return{}},f.offsetBounds=function(e){var n=e.offsetParent?f.offsetBounds(e.offsetParent):{top:0,left:0};return{top:e.offsetTop+n.top,bottom:e.offsetTop+e.offsetHeight+n.top,right:e.offsetLeft+n.left+e.offsetWidth,left:e.offsetLeft+n.left,width:e.offsetWidth,height:e.offsetHeight}},f.parseBackgrounds=function(e){var n,f,o,d,i,t,l,s=" \r\n ",u=[],a=0,p=0,c=function(){n&&('"'===f.substr(0,1)&&(f=f.substr(1,f.length-2)),f&&l.push(f),"-"===n.substr(0,1)&&(d=n.indexOf("-",1)+1)>0&&(o=n.substr(0,d),n=n.substr(d)),u.push({prefix:o,method:n.toLowerCase(),value:i,args:l,image:null})),l=[],n=o=f=i=""};return l=[],n=o=f=i="",e.split("").forEach(function(e){if(!(0===a&&s.indexOf(e)>-1)){switch(e){case'"':t?t===e&&(t=null):t=e;break;case"(":if(t)break;if(0===a)return a=1,void(i+=e);p++;break;case")":if(t)break;if(1===a){if(0===p)return a=0,i+=e,void c();p--}break;case",":if(t)break;if(0===a)return void c();if(1===a&&0===p&&!n.match(/^url$/i))return l.push(f),f="",void(i+=e)}i+=e,0===a?n+=e:f+=e}}),c(),u}},{}],30:[function(e,n){function f(e){o.apply(this,arguments),this.type="linear"===e.args[0]?this.TYPES.LINEAR:this.TYPES.RADIAL}var o=e("./gradientcontainer");f.prototype=Object.create(o.prototype),n.exports=f},{"./gradientcontainer":11}],31:[function(e,n){function f(e){return new o(function(n,f){var o=new XMLHttpRequest;o.open("GET",e),o.onload=function(){200===o.status?n(o.responseText):f(new Error(o.statusText))},o.onerror=function(){f(new Error("Network Error"))},o.send()})}var o=e("./promise");n.exports=f},{"./promise":18}]},{},[6])(6)}); \ No newline at end of file diff --git a/public/assets/js/libs/jsPDF-AutoTable/LICENSE.txt b/public/assets/js/libs/jsPDF-AutoTable/LICENSE.txt new file mode 100644 index 0000000000..2d5ec87f38 --- /dev/null +++ b/public/assets/js/libs/jsPDF-AutoTable/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2014 Simon Bengtsson, https://github.com/someatoms/jspdf-autotable + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/public/assets/js/libs/jsPDF-AutoTable/jspdf.plugin.autotable.js b/public/assets/js/libs/jsPDF-AutoTable/jspdf.plugin.autotable.js new file mode 100644 index 0000000000..71c2aad6aa --- /dev/null +++ b/public/assets/js/libs/jsPDF-AutoTable/jspdf.plugin.autotable.js @@ -0,0 +1,418 @@ +/** + * jsPDF AutoTable plugin + * Copyright (c) 2014 Simon Bengtsson, https://github.com/someatoms/jsPDF-AutoTable + * + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +(function (API) { + 'use strict'; + + // On every new jsPDF object, clear variables + API.events.push(['initialized', function () { + doc = undefined; + cellPos = undefined; + pageCount = 1; + settings = undefined; + }], false); + + var MIN_COLUMN_WIDTH = 25; + + var doc, cellPos, pageCount = 1, settings; + + // See README.md or examples for documentation of the options + // return a new instance every time to avoid references issues + var defaultOptions = function () { + return { + padding: 5, + fontSize: 10, + lineHeight: 20, + renderHeader: function (doc, pageNumber, settings) { + }, + renderFooter: function (doc, lastCellPos, pageNumber, settings) { + }, + renderHeaderCell: function (x, y, width, height, key, value, settings) { + doc.setFillColor(52, 73, 94); // Asphalt + doc.setTextColor(255, 255, 255); + doc.setFontStyle('bold'); + doc.rect(x, y, width, height, 'F'); + y += settings.lineHeight / 2 + API.autoTableTextHeight() / 2; + doc.text(value, x + settings.padding, y); + }, + renderCell: function (x, y, width, height, key, value, row, settings) { + doc.setFillColor(row % 2 === 0 ? 245 : 255); + doc.setTextColor(50); + doc.rect(x, y, width, height, 'F'); + y += settings.lineHeight / 2 + API.autoTableTextHeight() / 2 - 2.5; + doc.text(value, x + settings.padding, y); + }, + margins: {right: 40, left: 40, top: 50, bottom: 40}, + startY: false, + overflow: 'ellipsize', // false, ellipsize or linebreak (false passes the raw text to renderCell) + overflowColumns: false, // Specify which colums that gets subjected to the overflow method chosen. false indicates all + avoidPageSplit: false, + extendWidth: true + } + }; + + /** + * Create a table from a set of rows and columns. + * + * @param {Object[]|String[]} columns Either as an array of objects or array of strings + * @param {Object[][]|String[][]} data Either as an array of objects or array of strings + * @param {Object} [options={}] Options that will override the default ones (above) + */ + API.autoTable = function (columns, data, options) { + options = options || {}; + columns = columns || []; + doc = this; + + var userFontSize = doc.internal.getFontSize(); + + initData({columns: columns, data: data}); + initOptions(options); + + cellPos = { + x: settings.margins.left, + y: settings.startY === false ? settings.margins.top : settings.startY + }; + + var tableHeight = settings.margins.bottom + settings.margins.top + settings.lineHeight * (data.length + 1) + 5 + settings.startY; + if (settings.startY !== false && settings.avoidPageSplit && tableHeight > doc.internal.pageSize.height) { + pageCount++; + doc.addPage(); + cellPos.y = settings.margins.top; + } + + settings.renderHeader(doc, pageCount, settings); + var columnWidths = calculateColumnWidths(data, columns); + printHeader(columns, columnWidths); + printRows(columns, data, columnWidths); + settings.renderFooter(doc, cellPos, pageCount, settings); + + doc.setFontSize(userFontSize); + + return this; + }; + + /** + * Returns the Y position of the last drawn cell + * @returns int + */ + API.autoTableEndPosY = function () { + // If cellPos is not set, autoTable() has probably not been called + return cellPos ? cellPos.y : false; + }; + + /** + * @deprecated Use autoTableEndPosY() + */ + API.autoTableEndPos = function () { + return cellPos; + }; + + /** + * Parses an html table. To draw a table, use it like this: + * `doc.autoTable(false, doc.autoTableHtmlToJson(tableDomElem))` + * + * @param table Html table element + * @param indexBased Boolean flag if result should be returned as seperate cols and data + * @returns []|{} Array of objects with object keys as headers or based on indexes if indexBased is set to true + */ + API.autoTableHtmlToJson = function (table, indexBased) { + var data = [], headers = {}, header = table.rows[0], i, tableRow, rowData, j; + if (indexBased) { + headers = []; + for (i = 0; i < header.cells.length; i++) { + headers.push(header.cells[i] ? header.cells[i].textContent : ''); + } + + for (i = 1; i < table.rows.length; i++) { + tableRow = table.rows[i]; + rowData = []; + for (j = 0; j < header.cells.length; j++) { + rowData.push(tableRow.cells[j] ? tableRow.cells[j].textContent : ''); + } + data.push(rowData); + } + return {columns: headers, data: data}; + } else { + for (i = 0; i < header.cells.length; i++) { + headers[i] = header.cells[i] ? header.cells[i].textContent : ''; + } + + for (i = 1; i < table.rows.length; i++) { + tableRow = table.rows[i]; + rowData = {}; + for (j = 0; j < header.cells.length; j++) { + rowData[headers[j]] = tableRow.cells[j] ? tableRow.cells[j].textContent : ''; + } + data.push(rowData); + } + + return data; + } + }; + + /** + * Basically the same as getLineHeight() in 1.0+ versions of jsPDF, however + * added here for backwards compatibility with version 0.9 + * + * Export it to make it available in drawCell and drawHeaderCell + */ + API.autoTableTextHeight = function() { + // The value 1.15 comes from from the jsPDF source code and looks about right + return doc.internal.getFontSize() * 1.15; + }; + + /** + * Transform all to the object initialization form + * @param params + */ + function initData(params) { + + // Object only initial + if (!params.columns || params.columns.length === 0) { + var keys = Object.keys(params.data[0]); + Array.prototype.push.apply(params.columns, keys); + params.columns.forEach(function (title, i) { + params.columns[i] = {title: title, key: keys[i]}; + }); + } + // Array initialization form + else if (typeof params.columns[0] === 'string') { + params.data.forEach(function (row, i) { + var obj = {}; + for (var j = 0; j < row.length; j++) { + obj[j] = params.data[i][j]; + } + params.data[i] = obj; + }); + params.columns.forEach(function (title, i) { + params.columns[i] = {title: title, key: i}; + }); + } else { + // Use options as is + } + } + + function initOptions(raw) { + settings = defaultOptions(); + Object.keys(raw).forEach(function (key) { + settings[key] = raw[key]; + }); + doc.setFontSize(settings.fontSize); + + // Backwards compatibility + if(settings.margins.horizontal !== undefined) { + settings.margins.left = settings.margins.horizontal; + settings.margins.right = settings.margins.horizontal; + } else { + settings.margins.horizontal = settings.margins.left; + } + } + + function calculateColumnWidths(rows, columns) { + var widths = {}; + + // Optimal widths + var optimalTableWidth = 0; + columns.forEach(function (header) { + var widest = getStringWidth(header.title || '', true); + if(typeof header.width == "number") { + widest = header.width; + } else { + rows.forEach(function (row) { + if (!header.hasOwnProperty('key')) + throw new Error("The key attribute is required in every header"); + var w = getStringWidth(stringify(row, header.key)); + if (w > widest) { + widest = w; + } + }); + } + widths[header.key] = widest; + optimalTableWidth += widest; + }); + + var paddingAndMargin = settings.padding * 2 * columns.length + settings.margins.left + settings.margins.right; + var spaceDiff = doc.internal.pageSize.width - optimalTableWidth - paddingAndMargin; + + var keys = Object.keys(widths); + if (spaceDiff < 0) { + // Shrink columns + var shrinkableColumns = []; + var shrinkableColumnWidths = 0; + if (settings.overflowColumns === false) { + keys.forEach(function (key) { + if (widths[key] > MIN_COLUMN_WIDTH) { + shrinkableColumns.push(key); + shrinkableColumnWidths += widths[key]; + } + }); + } else { + shrinkableColumns = settings.overflowColumns; + shrinkableColumns.forEach(function (col) { + shrinkableColumnWidths += widths[col]; + }); + } + + shrinkableColumns.forEach(function (key) { + widths[key] += spaceDiff * (widths[key] / shrinkableColumnWidths); + }); + } else if (spaceDiff > 0 && settings.extendWidth) { + // Fill page horizontally + keys.forEach(function (key) { + widths[key] += spaceDiff / keys.length; + }); + } + + return widths; + } + + function printHeader(headers, columnWidths) { + if (!headers) return; + + // First calculate the height of the row + // (to do that the maxium amount of rows first need to be found) + var maxRows = 1; + if (settings.overflow === 'linebreak') { + // Font style must be the same as in function renderHeaderCell() + doc.setFontStyle('bold'); + + headers.forEach(function (header) { + if (isOverflowColumn(header)) { + var value = header.title || ''; + var arr = doc.splitTextToSize(value, columnWidths[header.key]); + if (arr.length > maxRows) { + maxRows = arr.length; + } + } + }); + } + var rowHeight = settings.lineHeight + (maxRows - 1) * API.autoTableTextHeight() + 5; + + // Avoid isolated table headers when drawing multiple tables. Add a new page + // if cellpos would be at the end of page after drawing the header row + var newPage = (cellPos.y + settings.margins.bottom + rowHeight * 2) >= doc.internal.pageSize.height; + if (newPage) { + settings.renderFooter(doc, cellPos, pageCount, settings); + doc.addPage(); + cellPos = {x: settings.margins.left, y: settings.margins.top}; + pageCount++; + settings.renderHeader(doc, pageCount, settings); + } + + headers.forEach(function (header) { + var width = columnWidths[header.key] + settings.padding * 2; + var value = header.title || ''; + if (settings.overflow === 'linebreak') { + if (isOverflowColumn(header)) { + value = doc.splitTextToSize(value, columnWidths[header.key]); + } + } else if (settings.overflow === 'ellipsize') { + value = ellipsize(columnWidths[header.key], value); + } + settings.renderHeaderCell(cellPos.x, cellPos.y, width, rowHeight, header.key, value, settings); + cellPos.x += width; + }); + doc.setTextColor(70, 70, 70); + doc.setFontStyle('normal'); + + cellPos.y += rowHeight; + cellPos.x = settings.margins.left; + } + + function printRows(headers, rows, columnWidths) { + for (var i = 0; i < rows.length; i++) { + var row = rows[i]; + + // First calculate the height of the row + // (to do that the maxium amount of rows first need to be found) + var maxRows = 1; + if (settings.overflow === 'linebreak') { + headers.forEach(function (header) { + if (isOverflowColumn(header)) { + var value = stringify(row, header.key); + var arr = doc.splitTextToSize(value, columnWidths[header.key]); + if (arr.length > maxRows) { + maxRows = arr.length; + } + } + }); + } + var rowHeight = settings.lineHeight + (maxRows - 1) * API.autoTableTextHeight(); + + + // Render the cell + headers.forEach(function (header) { + var value = stringify(row, header.key); + if (settings.overflow === 'linebreak') { + if (isOverflowColumn(header)) { + value = doc.splitTextToSize(value, columnWidths[header.key]); + } + } else if (settings.overflow === 'ellipsize') { + value = ellipsize(columnWidths[header.key], value); + } + var width = columnWidths[header.key] + settings.padding * 2; + settings.renderCell(cellPos.x, cellPos.y, width, rowHeight, header.key, value, i, settings); + cellPos.x = cellPos.x + columnWidths[header.key] + settings.padding * 2; + }); + + // Add a new page if cellpos is at the end of page + var newPage = (cellPos.y + settings.margins.bottom + rowHeight * 2) >= doc.internal.pageSize.height; + if (newPage) { + if (i+1 < rows.length) { + settings.renderFooter(doc, cellPos, pageCount, settings); + doc.addPage(); + cellPos = {x: settings.margins.left, y: settings.margins.top}; + pageCount++; + settings.renderHeader(doc, pageCount, settings); + printHeader(headers, columnWidths); + } + } else { + cellPos.y += rowHeight; + cellPos.x = settings.margins.left; + } + } + } + + function isOverflowColumn(header) { + return settings.overflowColumns === false || settings.overflowColumns.indexOf(header.key) !== -1; + } + + /** + * Ellipsize the text to fit in the width + * @param width + * @param text + */ + function ellipsize(width, text) { + if (width >= getStringWidth(text)) { + return text; + } + while (width < getStringWidth(text + "...")) { + if (text.length < 2) { + break; + } + text = text.substring(0, text.length - 1); + } + text += "..."; + return text; + } + + function stringify(row, key) { + return row.hasOwnProperty(key) ? '' + row[key] : ''; + } + + function getStringWidth(txt, isBold) { + if(isBold) { + doc.setFontStyle('bold'); + } + var strWidth = doc.getStringUnitWidth(txt) * doc.internal.getFontSize(); + if(isBold) { + doc.setFontStyle('normal'); + } + return strWidth; + } + +})(jsPDF.API); diff --git a/public/assets/js/libs/jsPDF/MIT-LICENSE.txt b/public/assets/js/libs/jsPDF/MIT-LICENSE.txt new file mode 100644 index 0000000000..2e06d0a1f2 --- /dev/null +++ b/public/assets/js/libs/jsPDF/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2010-2014 James Hall, https://github.com/MrRio/jsPDF + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/public/assets/js/libs/jsPDF/jspdf.min.js b/public/assets/js/libs/jsPDF/jspdf.min.js new file mode 100644 index 0000000000..c72711a95f --- /dev/null +++ b/public/assets/js/libs/jsPDF/jspdf.min.js @@ -0,0 +1,171 @@ +/** + * jsPDF - PDF Document creation from JavaScript + * Version 1.0.272-git Built on 2014-09-29T15:09 + * CommitID d4770725ca + * + * Copyright (c) 2010-2014 James Hall, https://github.com/MrRio/jsPDF + * 2010 Aaron Spike, https://github.com/acspike + * 2012 Willow Systems Corporation, willow-systems.com + * 2012 Pablo Hess, https://github.com/pablohess + * 2012 Florian Jenett, https://github.com/fjenett + * 2013 Warren Weckesser, https://github.com/warrenweckesser + * 2013 Youssef Beddad, https://github.com/lifof + * 2013 Lee Driscoll, https://github.com/lsdriscoll + * 2013 Stefan Slonevskiy, https://github.com/stefslon + * 2013 Jeremy Morel, https://github.com/jmorel + * 2013 Christoph Hartmann, https://github.com/chris-rock + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 James Makes, https://github.com/dollaruw + * 2014 Diego Casorran, https://github.com/diegocr + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango, + * kim3er, mfo, alnorth, + */ +/** + * jsPDF addHTML PlugIn + * Copyright (c) 2014 Diego Casorran + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +/** + * jsPDF addImage plugin + * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/ + * 2013 Chris Dowling, https://github.com/gingerchris + * 2013 Trinh Ho, https://github.com/ineedfat + * 2013 Edwin Alejandro Perez, https://github.com/eaparango + * 2013 Norah Smith, https://github.com/burnburnrocket + * 2014 Diego Casorran, https://github.com/diegocr + * 2014 James Robb, https://github.com/jamesbrobb + */ +/** + * jsPDF Cell plugin + * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com + * 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br + * 2013 Lee Driscoll, https://github.com/lsdriscoll + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 James Hall, james@parall.ax + * 2014 Diego Casorran, https://github.com/diegocr + */ +/** + * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser + * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 Diego Casorran, https://github.com/diegocr + * 2014 Daniel Husar, https://github.com/danielhusar + * 2014 Wolfgang Gassler, https://github.com/woolfg + */ +/** + * jsPDF JavaScript plugin + * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com + */ +/** + * jsPDF PNG PlugIn + * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb + */ +/** +jsPDF Silly SVG plugin +Copyright (c) 2012 Willow Systems Corporation, willow-systems.com +*/ +/** + * jsPDF split_text_to_size plugin - MIT license. + * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com + * 2014 Diego Casorran, https://github.com/diegocr + */ +/** +jsPDF standard_fonts_metrics plugin +Copyright (c) 2012 Willow Systems Corporation, willow-systems.com +MIT license. +*/ +/** + * jsPDF total_pages plugin + * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br + */ +/* Blob.js + * A Blob implementation. + * 2014-07-24 + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/dsamarin + * License: X11/MIT + * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md + */ +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 2014-08-29 + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ +/* + * Copyright (c) 2012 chick307 + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +/* + Deflate.js - https://github.com/gildas-lormeau/zip.js + Copyright (c) 2013 Gildas Lormeau. All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, + INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* +# PNG.js +# Copyright (c) 2011 Devon Govett +# MIT LICENSE +# +*/ +/* + * Extracted from pdf.js + * https://github.com/andreasgal/pdf.js + * Copyright (c) 2011 Mozilla Foundation + * Contributors: Andreas Gal + * Chris G Jones + * Shaon Barman + * Vivien Nicolas <21@vingtetun.org> + * Justin D'Arcangelo + * Yury Delendik + */ +/** + * JavaScript Polyfill functions for jsPDF + * Collected from public resources by + * https://github.com/diegocr + */ +!function(t,e){e["true"]=t;var n=function(t){"use strict";function e(e){var n={};this.subscribe=function(t,e,r){if("function"!=typeof e)return!1;n.hasOwnProperty(t)||(n[t]={});var s=Math.random().toString(35);return n[t][s]=[e,!!r],s},this.unsubscribe=function(t){for(var e in n)if(n[e][t])return delete n[e][t],!0;return!1},this.publish=function(r){if(n.hasOwnProperty(r)){var s=Array.prototype.slice.call(arguments,1),i=[];for(var o in n[r]){var a=n[r][o];try{a[0].apply(e,s)}catch(u){t.console&&console.error("jsPDF PubSub Error",u.message,u)}a[1]&&i.push(o)}i.length&&i.forEach(this.unsubscribe)}}}function n(a,u,c,l){var f={};"object"==typeof a&&(f=a,a=f.orientation,u=f.unit||u,c=f.format||c,l=f.compress||f.compressPdf||l),u=u||"mm",c=c||"a4",a=(""+(a||"P")).toLowerCase();var d,h,p,m,w,g,y,v,b,q=((""+c).toLowerCase(),!!l&&"function"==typeof Uint8Array),x=f.textColor||"0 g",k=f.drawColor||"0 G",_=f.fontSize||16,A=f.lineHeight||1.15,C=f.lineWidth||.200025,S=2,E=!1,z=[],T={},I={},B=0,O=[],P={},R=[],F=0,D=0,U=0,N={title:"",subject:"",author:"",keywords:"",creator:""},L={},j=new e(L),M=function(t){return t.toFixed(2)},H=function(t){return t.toFixed(3)},G=function(t){return("0"+parseInt(t)).slice(-2)},W=function(t){E?O[m].push(t):(U+=t.length+1,R.push(t))},V=function(){return S++,z[S]=U,W(S+" 0 obj"),S},J=function(t){W("stream"),W(t),W("endstream")},X=function(){var e,r,i,o,a,u,c,l,f;for(c=t.adler32cs||n.adler32cs,q&&"undefined"==typeof c&&(q=!1),e=1;B>=e;e++){if(V(),l=(w=P[e].width)*h,f=(g=P[e].height)*h,W("<>"),W("endobj"),r=O[e].join("\n"),V(),q){for(i=[],o=r.length;o--;)i[o]=r.charCodeAt(o);u=c.from(r),a=new s(6),a.append(new Uint8Array(i)),r=a.flush(),i=new Uint8Array(r.length+6),i.set(new Uint8Array([120,156])),i.set(r,2),i.set(new Uint8Array([255&u,u>>8&255,u>>16&255,u>>24&255]),r.length+2),r=String.fromCharCode.apply(null,i),W("<>")}else W("<>");J(r),W("endobj")}z[1]=U,W("1 0 obj"),W("<o;o++)d+=3+2*o+" 0 R ";W(d+"]"),W("/Count "+B),W(">>"),W("endobj")},Y=function(t){t.objectNumber=V(),W("<>"),W("endobj")},K=function(){for(var t in T)T.hasOwnProperty(t)&&Y(T[t])},Q=function(){j.publish("putXobjectDict")},$=function(){W("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),W("/Font <<");for(var t in T)T.hasOwnProperty(t)&&W("/"+t+" "+T[t].objectNumber+" 0 R");W(">>"),W("/XObject <<"),Q(),W(">>")},Z=function(){K(),j.publish("putResources"),z[2]=U,W("2 0 obj"),W("<<"),$(),W(">>"),W("endobj"),j.publish("postPutResources")},te=function(t,e,n){I.hasOwnProperty(e)||(I[e]={}),I[e][n]=t},ee=function(t,e,n,r){var s="F"+(Object.keys(T).length+1).toString(10),i=T[s]={id:s,PostScriptName:t,fontName:e,fontStyle:n,encoding:r,metadata:{}};return te(s,e,n),j.publish("addFont",i),s},ne=function(){for(var t="helvetica",e="times",n="courier",r="normal",s="bold",i="italic",o="bolditalic",a="StandardEncoding",u=[["Helvetica",t,r],["Helvetica-Bold",t,s],["Helvetica-Oblique",t,i],["Helvetica-BoldOblique",t,o],["Courier",n,r],["Courier-Bold",n,s],["Courier-Oblique",n,i],["Courier-BoldOblique",n,o],["Times-Roman",e,r],["Times-Bold",e,s],["Times-Italic",e,i],["Times-BoldItalic",e,o]],c=0,l=u.length;l>c;c++){var f=ee(u[c][0],u[c][1],u[c][2],a),d=u[c][0].split("-");te(f,d[0],d[1]||"")}j.publish("addFonts",{fonts:T,dictionary:I})},re=function(e){return e.foo=function(){try{return e.apply(this,arguments)}catch(n){var r=n.stack||"";~r.indexOf(" at ")&&(r=r.split(" at ")[1]);var s="Error in function "+r.split("\n")[0].split("<")[0]+": "+n.message;if(!t.console)throw new Error(s);t.console.error(s,n),t.alert&&alert(s)}},e.foo.bar=e,e.foo},se=function(t,e){var n,r,s,i,o,a,u,c,l;if(e=e||{},s=e.sourceEncoding||"Unicode",o=e.outputEncoding,(e.autoencode||o)&&T[d].metadata&&T[d].metadata[s]&&T[d].metadata[s].encoding&&(i=T[d].metadata[s].encoding,!o&&T[d].encoding&&(o=T[d].encoding),!o&&i.codePages&&(o=i.codePages[0]),"string"==typeof o&&(o=i[o]),o)){for(u=!1,a=[],n=0,r=t.length;r>n;n++)c=o[t.charCodeAt(n)],a.push(c?String.fromCharCode(c):t[n]),a[n].charCodeAt(0)>>8&&(u=!0);t=a.join("")}for(n=t.length;void 0===u&&0!==n;)t.charCodeAt(n-1)>>8&&(u=!0),n--;if(!u)return t;for(a=e.noBOM?[]:[254,255],n=0,r=t.length;r>n;n++){if(c=t.charCodeAt(n),l=c>>8,l>>8)throw new Error("Character at position "+n+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");a.push(l),a.push(c-(l<<8))}return String.fromCharCode.apply(void 0,a)},ie=function(t,e){return se(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},oe=function(){W("/Producer (jsPDF "+n.version+")");for(var t in N)N.hasOwnProperty(t)&&N[t]&&W("/"+t.substr(0,1).toUpperCase()+t.substr(1)+" ("+ie(N[t])+")");var e=new Date,r=e.getTimezoneOffset(),s=0>r?"+":"-",i=Math.floor(Math.abs(r/60)),o=Math.abs(r%60),a=[s,G(i),"'",G(o),"'"].join("");W(["/CreationDate (D:",e.getFullYear(),G(e.getMonth()+1),G(e.getDate()),G(e.getHours()),G(e.getMinutes()),G(e.getSeconds()),a,")"].join(""))},ae=function(){switch(W("/Type /Catalog"),W("/Pages 1 0 R"),v||(v="fullwidth"),v){case"fullwidth":W("/OpenAction [3 0 R /FitH null]");break;case"fullheight":W("/OpenAction [3 0 R /FitV null]");break;case"fullpage":W("/OpenAction [3 0 R /Fit]");break;case"original":W("/OpenAction [3 0 R /XYZ null null 1]");break;default:var t=""+v;"%"===t.substr(t.length-1)&&(v=parseInt(v)/100),"number"==typeof v&&W("/OpenAction [3 0 R /XYZ null null "+M(v)+"]")}switch(b||(b="continuous"),b){case"continuous":W("/PageLayout /OneColumn");break;case"single":W("/PageLayout /SinglePage");break;case"two":case"twoleft":W("/PageLayout /TwoColumnLeft");break;case"tworight":W("/PageLayout /TwoColumnRight")}y&&W("/PageMode /"+y),j.publish("putCatalog")},ue=function(){W("/Size "+(S+1)),W("/Root "+S+" 0 R"),W("/Info "+(S-1)+" 0 R")},ce=function(t,e){var n="string"==typeof e&&e.toLowerCase();if("string"==typeof t){var r=t.toLowerCase();o.hasOwnProperty(r)&&(t=o[r][0]/h,e=o[r][1]/h)}if(Array.isArray(t)&&(e=t[1],t=t[0]),n){switch(n.substr(0,1)){case"l":e>t&&(n="s");break;case"p":t>e&&(n="s")}"s"===n&&(p=t,t=e,e=p)}E=!0,O[++B]=[],P[B]={width:Number(t)||w,height:Number(e)||g},fe(B)},le=function(){ce.apply(this,arguments),W(M(C*h)+" w"),W(k),0!==F&&W(F+" J"),0!==D&&W(D+" j"),j.publish("addPage",{pageNumber:B})},fe=function(t){t>0&&B>=t&&(m=t,w=P[t].width,g=P[t].height)},de=function(t,e){var n;t=void 0!==t?t:T[d].fontName,e=void 0!==e?e:T[d].fontStyle;try{n=I[t][e]}catch(r){}if(!n)throw new Error("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts.");return n},he=function(){E=!1,S=2,R=[],z=[],W("%PDF-"+i),X(),Z(),V(),W("<<"),oe(),W(">>"),W("endobj"),V(),W("<<"),ae(),W(">>"),W("endobj");var t,e=U,n="0000000000";for(W("xref"),W("0 "+(S+1)),W(n+" 65535 f "),t=1;S>=t;t++)W((n+z[t]).slice(-10)+" 00000 n ");return W("trailer"),W("<<"),ue(),W(">>"),W("startxref"),W(e),W("%%EOF"),E=!0,R.join("\n")},pe=function(t){var e="S";return"F"===t?e="f":"FD"===t||"DF"===t?e="B":("f"===t||"f*"===t||"B"===t||"B*"===t)&&(e=t),e},me=function(){for(var t=he(),e=t.length,n=new ArrayBuffer(e),r=new Uint8Array(n);e--;)r[e]=t.charCodeAt(e);return n},we=function(){return new Blob([me()],{type:"application/pdf"})},ge=re(function(e,n){var s="dataur"===(""+e).substr(0,6)?"data:application/pdf;base64,"+btoa(he()):0;switch(e){case void 0:return he();case"save":if(navigator.getUserMedia&&(void 0===t.URL||void 0===t.URL.createObjectURL))return L.output("dataurlnewwindow");r(we(),n),"function"==typeof r.unload&&t.setTimeout&&setTimeout(r.unload,911);break;case"arraybuffer":return me();case"blob":return we();case"bloburi":case"bloburl":return t.URL&&t.URL.createObjectURL(we())||void 0;case"datauristring":case"dataurlstring":return s;case"dataurlnewwindow":var i=t.open(s);if(i||"undefined"==typeof safari)return i;case"datauri":case"dataurl":return t.document.location.href=s;default:throw new Error('Output type "'+e+'" is not supported.')}});switch(u){case"pt":h=1;break;case"mm":h=72/25.4;break;case"cm":h=72/2.54;break;case"in":h=72;break;case"px":h=96/72;break;case"pc":h=12;break;case"em":h=12;break;case"ex":h=6;break;default:throw"Invalid unit: "+u}L.internal={pdfEscape:ie,getStyle:pe,getFont:function(){return T[de.apply(L,arguments)]},getFontSize:function(){return _},getLineHeight:function(){return _*A},write:function(t){W(1===arguments.length?t:Array.prototype.join.call(arguments," "))},getCoordinateString:function(t){return M(t*h)},getVerticalCoordinateString:function(t){return M((g-t)*h)},collections:{},newObject:V,putStream:J,events:j,scaleFactor:h,pageSize:{get width(){return w},get height(){return g}},output:function(t,e){return ge(t,e)},getNumberOfPages:function(){return O.length-1},pages:O},L.addPage=function(){return le.apply(this,arguments),this},L.setPage=function(){return fe.apply(this,arguments),this},L.setDisplayMode=function(t,e,n){return v=t,b=e,y=n,this},L.text=function(t,e,n,r,s){function i(t){return t=t.split(" ").join(Array(f.TabLen||9).join(" ")),ie(t,r)}"number"==typeof t&&(p=n,n=e,e=t,t=p),"string"==typeof t&&t.match(/[\n\r]/)&&(t=t.split(/\r\n|\r|\n/g)),"number"==typeof r&&(s=r,r=null);var o,a="",u="Td";if(s){s*=Math.PI/180;var c=Math.cos(s),l=Math.sin(s);a=[M(c),M(l),M(-1*l),M(c),""].join(" "),u="Tm"}if(r=r||{},"noBOM"in r||(r.noBOM=!0),"autoencode"in r||(r.autoencode=!0),"string"==typeof t)t=i(t);else{if(!(t instanceof Array))throw new Error('Type of text must be string or Array. "'+t+'" is not recognized.');for(var m=t.concat(),w=[],y=m.length;y--;)w.push(i(m.shift()));var v=Math.ceil((g-n)*h/(_*A));v>=0&&vs;s++,e+=r)this.text(t[s],e,n)},L.line=function(t,e,n,r){return this.lines([[n-t,r-e]],t,e)},L.clip=function(){W("W"),W("S")},L.lines=function(t,e,n,r,s,i){var o,a,u,c,l,f,d,m,w,y,v;for("number"==typeof t&&(p=n,n=e,e=t,t=p),r=r||[1,1],W(H(e*h)+" "+H((g-n)*h)+" m "),o=r[0],a=r[1],c=t.length,y=e,v=n,u=0;c>u;u++)l=t[u],2===l.length?(y=l[0]*o+y,v=l[1]*a+v,W(H(y*h)+" "+H((g-v)*h)+" l")):(f=l[0]*o+y,d=l[1]*a+v,m=l[2]*o+y,w=l[3]*a+v,y=l[4]*o+y,v=l[5]*a+v,W(H(f*h)+" "+H((g-d)*h)+" "+H(m*h)+" "+H((g-w)*h)+" "+H(y*h)+" "+H((g-v)*h)+" c"));return i&&W(" h"),null!==s&&W(pe(s)),this},L.rect=function(t,e,n,r,s){pe(s);return W([M(t*h),M((g-e)*h),M(n*h),M(-r*h),"re"].join(" ")),null!==s&&W(pe(s)),this},L.triangle=function(t,e,n,r,s,i,o){return this.lines([[n-t,r-e],[s-n,i-r],[t-s,e-i]],t,e,[1,1],o,!0),this},L.roundedRect=function(t,e,n,r,s,i,o){var a=4/3*(Math.SQRT2-1);return this.lines([[n-2*s,0],[s*a,0,s,i-i*a,s,i],[0,r-2*i],[0,i*a,-(s*a),i,-s,i],[-n+2*s,0],[-(s*a),0,-s,-(i*a),-s,-i],[0,-r+2*i],[0,-(i*a),s*a,-i,s,-i]],t+s,e,[1,1],o),this},L.ellipse=function(t,e,n,r,s){var i=4/3*(Math.SQRT2-1)*n,o=4/3*(Math.SQRT2-1)*r;return W([M((t+n)*h),M((g-e)*h),"m",M((t+n)*h),M((g-(e-o))*h),M((t+i)*h),M((g-(e-r))*h),M(t*h),M((g-(e-r))*h),"c"].join(" ")),W([M((t-i)*h),M((g-(e-r))*h),M((t-n)*h),M((g-(e-o))*h),M((t-n)*h),M((g-e)*h),"c"].join(" ")),W([M((t-n)*h),M((g-(e+o))*h),M((t-i)*h),M((g-(e+r))*h),M(t*h),M((g-(e+r))*h),"c"].join(" ")),W([M((t+i)*h),M((g-(e+r))*h),M((t+n)*h),M((g-(e+o))*h),M((t+n)*h),M((g-e)*h),"c"].join(" ")),null!==s&&W(pe(s)),this},L.circle=function(t,e,n,r){return this.ellipse(t,e,n,n,r)},L.setProperties=function(t){for(var e in N)N.hasOwnProperty(e)&&t[e]&&(N[e]=t[e]);return this},L.setFontSize=function(t){return _=t,this},L.setFont=function(t,e){return d=de(t,e),this},L.setFontStyle=L.setFontType=function(t){return d=de(void 0,t),this},L.getFontList=function(){var t,e,n,r={};for(t in I)if(I.hasOwnProperty(t)){r[t]=n=[];for(e in I[t])I[t].hasOwnProperty(e)&&n.push(e)}return r},L.setLineWidth=function(t){return W((t*h).toFixed(2)+" w"),this},L.setDrawColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" G":M(t/255)+" G":void 0===r?"string"==typeof t?[t,e,n,"RG"].join(" "):[M(t/255),M(e/255),M(n/255),"RG"].join(" "):"string"==typeof t?[t,e,n,r,"K"].join(" "):[M(t),M(e),M(n),M(r),"K"].join(" "),W(s),this},L.setFillColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" g":M(t/255)+" g":void 0===r?"string"==typeof t?[t,e,n,"rg"].join(" "):[M(t/255),M(e/255),M(n/255),"rg"].join(" "):"string"==typeof t?[t,e,n,r,"k"].join(" "):[M(t),M(e),M(n),M(r),"k"].join(" "),W(s),this},L.setTextColor=function(t,e,n){if("string"==typeof t&&/^#[0-9A-Fa-f]{6}$/.test(t)){var r=parseInt(t.substr(1),16);t=r>>16&255,e=r>>8&255,n=255&r}return x=0===t&&0===e&&0===n||"undefined"==typeof e?H(t/255)+" g":[H(t/255),H(e/255),H(n/255),"rg"].join(" "),this},L.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},L.setLineCap=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line cap style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return F=e,W(e+" J"),this},L.setLineJoin=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line join style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return D=e,W(e+" j"),this},L.output=ge,L.save=function(t){L.output("save",t)};for(var ye in n.API)n.API.hasOwnProperty(ye)&&("events"===ye&&n.API.events.length?!function(t,e){var n,r,s;for(s=e.length-1;-1!==s;s--)n=e[s][0],r=e[s][1],t.subscribe.apply(t,[n].concat("function"==typeof r?[r]:r))}(j,n.API.events):L[ye]=n.API[ye]);return ne(),d="F1",le(c,a),j.publish("initialized"),L}var i="1.3",o={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};return n.API={events:[]},n.version="1.0.272-git 2014-09-29T15:09:diegocr","function"==typeof define&&define.amd?define("jsPDF",function(){return n}):t.jsPDF=n,n}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);!function(t){"use strict";t.addHTML=function(t,e,n,r,s){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof e&&(r=e,s=n),"function"==typeof r&&(s=r,r=null);var i=this.internal,o=i.scaleFactor,a=i.pageSize.width,u=i.pageSize.height;if(r=r||{},r.onrendered=function(t){e=parseInt(e)||0,n=parseInt(n)||0;var i=r.dim||{},c=i.h||0,l=i.w||Math.min(a,t.width/o)-e,f="JPEG";if(r.format&&(f=r.format),t.height>u&&r.pagesplit){var d=function(){for(var r=0;;){var i=document.createElement("canvas");i.width=Math.min(a*o,t.width),i.height=Math.min(u*o,t.height-r);var c=i.getContext("2d");c.drawImage(t,0,r,t.width,i.height,0,0,i.width,i.height);var d=[i,e,r?0:n,i.width/o,i.height/o,f,null,"SLOW"];if(this.addImage.apply(this,d),r+=i.height,r>=t.height)break;this.addPage()}s(l,r,null,d)}.bind(this);if("CANVAS"===t.nodeName){var h=new Image;h.onload=d,h.src=t.toDataURL("image/png"),t=h}else d()}else{var p=Math.random().toString(35),m=[t,e,n,l,c,f,p,"SLOW"];this.addImage.apply(this,m),s(l,c,p,m)}}.bind(this),"undefined"!=typeof html2canvas&&!r.rstz)return html2canvas(t,r);if("undefined"!=typeof rasterizeHTML){var c="drawDocument";return"string"==typeof t&&(c=/^http/.test(t)?"drawURL":"drawHTML"),r.width=r.width||a*o,rasterizeHTML[c](t,void 0,r).then(function(t){r.onrendered(t.image)},function(t){s(null,t)})}return null}}(n.API),function(t){"use strict";var e="addImage_",n=["jpeg","jpg","png"],r=function(t){var e=this.internal.newObject(),n=this.internal.write,s=this.internal.putStream;if(t.n=e,n("<>"),"trns"in t&&t.trns.constructor==Array){for(var i="",o=0,a=t.trns.length;a>o;o++)i+=t.trns[o]+" "+t.trns[o]+" ";n("/Mask ["+i+"]")}if("smask"in t&&n("/SMask "+(e+1)+" 0 R"),n("/Length "+t.data.length+">>"),s(t.data),n("endobj"),"smask"in t){var u="/Predictor 15 /Colors 1 /BitsPerComponent "+t.bpc+" /Columns "+t.w,c={w:t.w,h:t.h,cs:"DeviceGray",bpc:t.bpc,dp:u,data:t.smask};"f"in t&&(c.f=t.f),r.call(this,c)}t.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),n("<< /Length "+t.pal.length+">>"),s(this.arrayBufferToBinaryString(new Uint8Array(t.pal))),n("endobj"))},s=function(){var t=this.internal.collections[e+"images"];for(var n in t)r.call(this,t[n])},i=function(){var t,n=this.internal.collections[e+"images"],r=this.internal.write;for(var s in n)t=n[s],r("/I"+t.i,t.n,"0","R")},o=function(e){return e&&"string"==typeof e&&(e=e.toUpperCase()),e in t.image_compression?e:t.image_compression.NONE},a=function(){var t=this.internal.collections[e+"images"];return t||(this.internal.collections[e+"images"]=t={},this.internal.events.subscribe("putResources",s),this.internal.events.subscribe("putXobjectDict",i)),t},u=function(t){var e=0;return t&&(e=Object.keys?Object.keys(t).length:function(t){var e=0;for(var n in t)t.hasOwnProperty(n)&&e++;return e}(t)),e},c=function(t){return"undefined"==typeof t||null===t},l=function(e){return"string"==typeof e&&t.sHashCode(e)},f=function(t){return-1===n.indexOf(t)},d=function(e){return"function"!=typeof t["process"+e.toUpperCase()]},h=function(t){return"object"==typeof t&&1===t.nodeType},p=function(t,e,n){if("IMG"===t.nodeName&&t.hasAttribute("src")){var r=""+t.getAttribute("src");if(!n&&0===r.indexOf("data:image/"))return r;!e&&/\.png(?:[?#].*)?$/i.test(r)&&(e="png")}if("CANVAS"===t.nodeName)var s=t;else{var s=document.createElement("canvas");s.width=t.clientWidth||t.width,s.height=t.clientHeight||t.height;var i=s.getContext("2d");if(!i)throw"addImage requires canvas to be supported by browser.";if(n){var o,a,u,c,l,f,d,h,p=Math.PI/180;"object"==typeof n&&(o=n.x,a=n.y,u=n.bg,n=n.angle),h=n*p,c=Math.abs(Math.cos(h)),l=Math.abs(Math.sin(h)),f=s.width,d=s.height,s.width=d*l+f*c,s.height=d*c+f*l,isNaN(o)&&(o=s.width/2),isNaN(a)&&(a=s.height/2),i.clearRect(0,0,s.width,s.height),i.fillStyle=u||"white",i.fillRect(0,0,s.width,s.height),i.save(),i.translate(o,a),i.rotate(h),i.drawImage(t,-(f/2),-(d/2)),i.rotate(-h),i.translate(-o,-a),i.restore()}else i.drawImage(t,0,0,s.width,s.height)}return s.toDataURL("png"==(""+e).toLowerCase()?"image/png":"image/jpeg")},m=function(t,e){var n;if(e)for(var r in e)if(t===e[r].alias){n=e[r];break}return n},w=function(t,e,n){return t||e||(t=-96,e=-96),0>t&&(t=-1*n.w*72/t/this.internal.scaleFactor),0>e&&(e=-1*n.h*72/e/this.internal.scaleFactor),0===t&&(t=e*n.w/n.h),0===e&&(e=t*n.h/n.w),[t,e]},g=function(t,e,n,r,s,i,o){var a=w.call(this,n,r,s),u=this.internal.getCoordinateString,c=this.internal.getVerticalCoordinateString;n=a[0],r=a[1],o[i]=s,this.internal.write("q",u(n),"0 0",u(r),u(t),c(e+r),"cm /I"+s.i,"Do Q")};t.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPERATION:"Seperation",DEVICE_N:"DeviceN"},t.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},t.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},t.sHashCode=function(t){return Array.prototype.reduce&&t.split("").reduce(function(t,e){return t=(t<<5)-t+e.charCodeAt(0),t&t},0)},t.isString=function(t){return"string"==typeof t},t.extractInfoFromBase64DataURI=function(t){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(t)},t.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},t.isArrayBuffer=function(t){return this.supportsArrayBuffer()?t instanceof ArrayBuffer:!1},t.isArrayBufferView=function(t){return this.supportsArrayBuffer()?"undefined"==typeof Uint32Array?!1:t instanceof Int8Array||t instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array:!1},t.binaryStringToUint8Array=function(t){for(var e=t.length,n=new Uint8Array(e),r=0;e>r;r++)n[r]=t.charCodeAt(r);return n},t.arrayBufferToBinaryString=function(t){this.isArrayBuffer(t)&&(t=new Uint8Array(t));for(var e="",n=t.byteLength,r=0;n>r;r++)e+=String.fromCharCode(t[r]);return e},t.arrayBufferToBase64=function(t){for(var e,n,r,s,i,o="",a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=new Uint8Array(t),c=u.byteLength,l=c%3,f=c-l,d=0;f>d;d+=3)i=u[d]<<16|u[d+1]<<8|u[d+2],e=(16515072&i)>>18,n=(258048&i)>>12,r=(4032&i)>>6,s=63&i,o+=a[e]+a[n]+a[r]+a[s];return 1==l?(i=u[f],e=(252&i)>>2,n=(3&i)<<4,o+=a[e]+a[n]+"=="):2==l&&(i=u[f]<<8|u[f+1],e=(64512&i)>>10,n=(1008&i)>>4,r=(15&i)<<2,o+=a[e]+a[n]+a[r]+"="),o},t.createImageInfo=function(t,e,n,r,s,i,o,a,u,c,l,f){var d={alias:a,w:e,h:n,cs:r,bpc:s,i:o,data:t};return i&&(d.f=i),u&&(d.dp=u),c&&(d.trns=c),l&&(d.pal=l),f&&(d.smask=f),d},t.addImage=function(t,e,r,s,i,w,y,v,b){if("string"!=typeof e){var q=w;w=i,i=s,s=r,r=e,e=q}if("object"==typeof t&&!h(t)&&"imageData"in t){var x=t;t=x.imageData,e=x.format||e,r=x.x||r||0,s=x.y||s||0,i=x.w||i,w=x.h||w,y=x.alias||y,v=x.compression||v,b=x.rotation||x.angle||b}if(isNaN(r)||isNaN(s))throw console.error("jsPDF.addImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addImage");var k,_=a.call(this);if(!(k=m(t,_))){var A;if(h(t)&&(t=p(t,e,b)),c(y)&&(y=l(t)),!(k=m(y,_))){if(this.isString(t)){var C=this.extractInfoFromBase64DataURI(t);C?(e=C[2],t=atob(C[3])):137===t.charCodeAt(0)&&80===t.charCodeAt(1)&&78===t.charCodeAt(2)&&71===t.charCodeAt(3)&&(e="png")}if(e=(e||"JPEG").toLowerCase(),f(e))throw new Error("addImage currently only supports formats "+n+", not '"+e+"'");if(d(e))throw new Error("please ensure that the plugin for '"+e+"' support is added");if(this.supportsArrayBuffer()&&(A=t,t=this.binaryStringToUint8Array(t)),k=this["process"+e.toUpperCase()](t,u(_),y,o(v),A),!k)throw new Error("An unkwown error occurred whilst processing the image")}}return g.call(this,r,s,i,w,k,k.i,_),this};var y=function(t){var e,n,r;if(255===!t.charCodeAt(0)||216===!t.charCodeAt(1)||255===!t.charCodeAt(2)||224===!t.charCodeAt(3)||!t.charCodeAt(6)==="J".charCodeAt(0)||!t.charCodeAt(7)==="F".charCodeAt(0)||!t.charCodeAt(8)==="I".charCodeAt(0)||!t.charCodeAt(9)==="F".charCodeAt(0)||0===!t.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var s=256*t.charCodeAt(4)+t.charCodeAt(5),i=4,o=t.length;o>i;){if(i+=s,255!==t.charCodeAt(i))throw new Error("getJpegSize could not find the size of the image");if(192===t.charCodeAt(i+1)||193===t.charCodeAt(i+1)||194===t.charCodeAt(i+1)||195===t.charCodeAt(i+1)||196===t.charCodeAt(i+1)||197===t.charCodeAt(i+1)||198===t.charCodeAt(i+1)||199===t.charCodeAt(i+1))return n=256*t.charCodeAt(i+5)+t.charCodeAt(i+6),e=256*t.charCodeAt(i+7)+t.charCodeAt(i+8),r=t.charCodeAt(i+9),[e,n,r];i+=2,s=256*t.charCodeAt(i)+t.charCodeAt(i+1)}},v=function(t){var e=t[0]<<8|t[1];if(65496!==e)throw new Error("Supplied data is not a JPEG");for(var n,r,s,i,o=t.length,a=(t[4]<<8)+t[5],u=4;o>u;){if(u+=a,n=b(t,u),a=(n[2]<<8)+n[3],(192===n[1]||194===n[1])&&255===n[0]&&a>7)return n=b(t,u+5),r=(n[2]<<8)+n[3],s=(n[0]<<8)+n[1],i=n[4],{width:r,height:s,numcomponents:i};u+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")},b=function(t,e){return t.subarray(e,e+5)};t.processJPEG=function(t,e,n,r,s){var i,o=this.color_spaces.DEVICE_RGB,a=this.decode.DCT_DECODE,u=8;return this.isString(t)?(i=y(t),this.createImageInfo(t,i[0],i[1],1==i[3]?this.color_spaces.DEVICE_GRAY:o,u,a,e,n)):(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)?(i=v(t),t=s||this.arrayBufferToBinaryString(t),this.createImageInfo(t,i.width,i.height,1==i.numcomponents?this.color_spaces.DEVICE_GRAY:o,u,a,e,n)):null)},t.processJPG=function(){return this.processJPEG.apply(this,arguments)}}(n.API),function(t){"use strict";t.autoPrint=function(){var t;return this.internal.events.subscribe("postPutResources",function(){t=this.internal.newObject(),this.internal.write("<< /S/Named /Type/Action /N/Print >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.write("/OpenAction "+t+" 0 R")}),this}}(n.API),function(t){"use strict";var e,n,r,s,i=3,o=13,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,c=function(t,e,n,r,s){a={x:t,y:e,w:n,h:r,ln:s}},l=function(){return a},f={left:0,top:0,bottom:0};t.setHeaderFunction=function(t){s=t},t.getTextDimensions=function(t){e=this.internal.getFont().fontName,n=this.table_font_size||this.internal.getFontSize(),r=this.internal.getFont().fontStyle;var s,i,o=19.049976/25.4;return i=document.createElement("font"),i.id="jsPDFCell",i.style.fontStyle=r,i.style.fontName=e,i.style.fontSize=n+"pt",i.textContent=t,document.body.appendChild(i),s={w:(i.offsetWidth+1)*o,h:(i.offsetHeight+1)*o},document.body.removeChild(i),s},t.cellAddPage=function(){var t=this.margins||f;this.addPage(),c(t.left,t.top,void 0,void 0),u+=1},t.cellInitialize=function(){a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1},t.cell=function(t,e,n,r,s,a,u){var d=l();if(void 0!==d.ln)if(d.ln===a)t=d.x+d.w,e=d.y;else{var h=this.margins||f;d.y+d.h+r+o>=this.internal.pageSize.height-h.bottom&&(this.cellAddPage(),this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(a,!0)),e=l().y+l().h}if(void 0!==s[0])if(this.printingHeaderRow?this.rect(t,e,n,r,"FD"):this.rect(t,e,n,r),"right"===u){if(s instanceof Array)for(var p=0;pn;n+=1)s=t[n],e?-1===e(i,s)&&(i=s):s>i&&(i=s);return i},t.table=function(e,n,r,s,i){if(!r)throw"No data for PDF table";var o,c,l,d,h,p,m,w,g,y,v=[],b=[],q={},x={},k=[],_=[],A=!1,C=!0,S=12,E=f;if(E.width=this.internal.pageSize.width,i&&(i.autoSize===!0&&(A=!0),i.printHeaders===!1&&(C=!1),i.fontSize&&(S=i.fontSize),i.margins&&(E=i.margins)),this.lnMod=0,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,this.printHeaders=C,this.margins=E,this.setFontSize(S),this.table_font_size=S,void 0===s||null===s)v=Object.keys(r[0]);else if(s[0]&&"string"!=typeof s[0]){var z=19.049976/25.4;for(c=0,l=s.length;l>c;c+=1)o=s[c],v.push(o.name),b.push(o.prompt),x[o.name]=o.width*z}else v=s;if(A)for(y=function(t){return t[o]},c=0,l=v.length;l>c;c+=1){for(o=v[c],q[o]=r.map(y),k.push(this.getTextDimensions(b[c]||o).w),p=q[o],m=0,d=p.length;d>m;m+=1)h=p[m],k.push(this.getTextDimensions(h).w);x[o]=t.arrayMax(k)}if(C){var T=this.calculateLineHeight(v,x,b.length?b:v);for(c=0,l=v.length;l>c;c+=1)o=v[c],_.push([e,n,x[o],T,String(b.length?b[c]:o)]);this.setTableHeaderRow(_),this.printHeaderRow(1,!1)}for(c=0,l=r.length;l>c;c+=1){var T;for(w=r[c],T=this.calculateLineHeight(v,x,w),m=0,g=v.length;g>m;m+=1)o=v[m],this.cell(e,n,x[o],T,w[o],c+2,o.align)}return this.lastCellPos=a,this.table_x=e,this.table_y=n,this},t.calculateLineHeight=function(t,e,n){for(var r,s=0,o=0;os&&(s=a)}return s},t.setTableHeaderRow=function(t){this.tableHeaderRow=t},t.printHeaderRow=function(t,e){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var n,r,i,o;if(this.printingHeaderRow=!0,void 0!==s){var a=s(this,u);c(a[0],a[1],a[2],a[3],-1)}this.setFontStyle("bold");var l=[];for(i=0,o=this.tableHeaderRow.length;o>i;i+=1)this.setFillColor(200,200,200),n=this.tableHeaderRow[i],e&&(n[1]=this.margins&&this.margins.top||0,l.push(n)),r=[].concat(n),this.cell.apply(this,r.concat(t));l.length>0&&this.setTableHeaderRow(l),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(n.API),function(t){var e,n,r,s,i,o,a,u,c,l,f,d,h,p,m,w,g,y,v;e=function(){function t(){}return function(e){return t.prototype=e,new t}}(),c=function(t){var e,n,r,s,i,o,a;for(n=0,r=t.length,e=void 0,s=!1,o=!1;!s&&n!==r;)e=t[n]=t[n].trimLeft(),e&&(s=!0),n++;for(n=r-1;r&&!o&&-1!==n;)e=t[n]=t[n].trimRight(),e&&(o=!0),n--;for(i=/\s+$/g,a=!0,n=0;n!==r;)e=t[n].replace(/\s+/g," "),a&&(e=e.trimLeft()),e&&(a=i.test(e)),t[n]=e,n++;return t},l=function(t,e,n,r){return this.pdf=t,this.x=e,this.y=n,this.settings=r,this.watchFunctions=[],this.init(),this},f=function(t){var e,n,s;for(e=void 0,s=t.split(","),n=s.shift();!e&&n;)e=r[n.trim().toLowerCase()],n=s.shift();return e},d=function(t){t="auto"===t?"0px":t,t.indexOf("em")>-1&&!isNaN(Number(t.replace("em","")))&&(t=18.719*Number(t.replace("em",""))+"px"),t.indexOf("pt")>-1&&!isNaN(Number(t.replace("pt","")))&&(t=1.333*Number(t.replace("pt",""))+"px");var e,n,r;return n=void 0,e=16,(r=h[t])?r:(r={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:t}],r!==n?h[t]=r/e:(r=parseFloat(t))?h[t]=r/e:(r=t.match(/([\d\.]+)(px)/),h[t]=3===r.length?parseFloat(r[1])/e:1))},u=function(t){var e,n,r;return r=function(t){var e;return e=function(t){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(t,null):t.currentStyle?t.currentStyle:t.style}(t),function(t){return t=t.replace(/-\D/g,function(t){return t.charAt(1).toUpperCase()}),e[t]}}(t),e={},n=void 0,e["font-family"]=f(r("font-family"))||"times",e["font-style"]=s[r("font-style")]||"normal",e["text-align"]=TextAlignMap[r("text-align")]||"left",n=i[r("font-weight")]||"normal","bold"===n&&(e["font-style"]="normal"===e["font-style"]?n:n+e["font-style"]),e["font-size"]=d(r("font-size"))||1,e["line-height"]=d(r("line-height"))||1,e.display="inline"===r("display")?"inline":"block",n="block"===e.display,e["margin-top"]=n&&d(r("margin-top"))||0,e["margin-bottom"]=n&&d(r("margin-bottom"))||0,e["padding-top"]=n&&d(r("padding-top"))||0,e["padding-bottom"]=n&&d(r("padding-bottom"))||0,e["margin-left"]=n&&d(r("margin-left"))||0,e["margin-right"]=n&&d(r("margin-right"))||0,e["padding-left"]=n&&d(r("padding-left"))||0,e["padding-right"]=n&&d(r("padding-right"))||0,e["float"]=o[r("cssFloat")]||"none",e.clear=a[r("clear")]||"none",e},p=function(t,e,n){var r,s,i,o,a;if(i=!1,s=void 0,o=void 0,a=void 0,r=n["#"+t.id])if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;if(r=n[t.nodeName],!i&&r)if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;return i},v=function(t,e){var n,r,s,i,o,a,u,c,l,f; +for(n=[],r=[],s=0,f=t.rows[0].cells.length,c=t.clientWidth;f>s;)l=t.rows[0].cells[s],r[s]={name:l.textContent.toLowerCase().replace(/\s+/g,""),prompt:l.textContent.replace(/\r?\n/g,""),width:l.clientWidth/c*e.pdf.internal.pageSize.width},s++;for(s=1;sa;){if(s=i[a],"object"==typeof s){if(e.executeWatchFunctions(s),1===s.nodeType&&"HEADER"===s.nodeName){var w=s,g=e.pdf.margins_doc.top;e.pdf.internal.events.subscribe("addPage",function(){e.y=g,n(w,e,r),e.pdf.margins_doc.top=e.y+10,e.y+=10},!1)}if(8===s.nodeType&&"#comment"===s.nodeName)~s.textContent.indexOf("ADD_PAGE")&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top);else if(1!==s.nodeType||b[s.nodeName])if(3===s.nodeType){var y=s.nodeValue;if(s.nodeValue&&"LI"===s.parentNode.nodeName)if("OL"===s.parentNode.parentNode.nodeName)y=q++ +". "+y;else{var x=16*o["font-size"],k=2;x>20&&(k=3),h=function(t,e){this.pdf.circle(t,e,k,"FD")}}e.addText(y,o)}else"string"==typeof s&&e.addText(s,o);else{var _;if("IMG"===s.nodeName){var A=s.getAttribute("src");_=m[e.pdf.sHashCode(A)||A]}if(_){e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottome.pdf.margins_doc.top&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top,e.executeWatchFunctions(s));var C=u(s),S=e.x,E=12/e.pdf.internal.scaleFactor,z=(C["margin-left"]+C["padding-left"])*E,T=(C["margin-right"]+C["padding-right"])*E,I=(C["margin-top"]+C["padding-top"])*E,B=(C["margin-bottom"]+C["padding-bottom"])*E;S+=void 0!==C["float"]&&"right"===C["float"]?e.settings.width-s.width-T:z,e.pdf.addImage(_,S,e.y+I,s.width,s.height),_=void 0,"right"===C["float"]||"left"===C["float"]?(e.watchFunctions.push(function(t,n,r,s){return e.y>=n?(e.x+=t,e.settings.width+=r,!0):s&&1===s.nodeType&&!b[s.nodeName]&&e.x+s.width>e.pdf.margins_doc.left+e.pdf.margins_doc.width?(e.x+=t,e.y=n,e.settings.width+=r,!0):!1}.bind(this,"left"===C["float"]?-s.width-z-T:0,e.y+s.height+I+B,s.width)),e.watchFunctions.push(function(t,n,r){return e.y0){s=s[0];var i=e.pdf.internal.write,o=e.y;e.pdf.internal.write=function(){},n(s,e,r);var a=Math.ceil(e.y-o)+5;e.y=o,e.pdf.internal.write=i,e.pdf.margins_doc.bottom+=a;for(var u=function(t){var i=void 0!==t?t.pageNumber:1,o=e.y;e.y=e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottom,e.pdf.margins_doc.bottom-=a;for(var u=s.getElementsByTagName("span"),c=0;c-1&&(u[c].innerHTML=i),(" "+u[c].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&(u[c].innerHTML="###jsPDFVarTotalPages###");n(s,e,r),e.pdf.margins_doc.bottom+=a,e.y=o},c=s.getElementsByTagName("span"),l=0;l-1&&e.pdf.internal.events.subscribe("htmlRenderingFinished",e.pdf.putTotalPages.bind(e.pdf,"###jsPDFVarTotalPages###"),!0);e.pdf.internal.events.subscribe("addPage",u,!1),u(),b.FOOTER=1}},y=function(t,e,r,s,i,o){if(!e)return!1;"string"==typeof e||e.parentNode||(e=""+e.innerHTML),"string"==typeof e&&(e=function(t){var e,n,r,s;return r="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),s="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",n=document.createElement("div"),n.style.cssText=s,n.innerHTML='