图片上传预览并保存图片 | 多图上传预览并保存图片 | 树状结构(jquery.treeview.js)
一:引入文件:bootstrap.min.css bootstrap-fileinput.css jquery.js bootstrap.min.js bootstrap-fileinput.js
index.html
<html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css"> <link rel="stylesheet" href="bootstrap-fileinput.css"> <!--使用Bootstrap的js插件,必须先调入jQuery--> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script> <!-- 包括所有bootstrap的js插件或者可以根据需要使用的js插件调用 --> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script src="bootstrap-fileinput.js"></script> </head> <body> <div class="fileinput fileinput-new" data-provides="fileinput" id="uploadImageDiv"> <div class="fileinput-new thumbnail" style="width: 200px; height: 150px;"> <img src="1.jpg" alt="" /> </div> <div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;"></div> <div> <span class="btn default btn-file"> <span class="fileinput-new">选择图片</span> <span class="fileinput-exists">更改</span> <input type="file" name="uploadImage" id="uploadImage" /> </span> <a href="#" class="btn default fileinput-exists" data-dismiss="fileinput">移除</a> <span>请选择1M以内图片</span> </div> </div> <button class='sub'>提交</button> </body> <script> $(document).ready(function(){ $('.sub').click(function(){ $.post('index.php',{src:$('.photo').val()},function(data){ console.log(data) },'json'); }) }) </script> </html>
index.php php处理base64数据
<?php $url = base64_image_content($_REQUEST['src'],'upload'); echo json_encode($url); function base64_image_content($base64_image_content,$path){ //匹配出图片的格式 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){ $type = $result[2]; //$ff=date('Y-m-d',time()); $new_file = $_SERVER['DOCUMENT_ROOT'].'/'.$path.'/'; if(!file_exists($new_file)){ //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($new_file, 0700); } $picname=mt_rand(0,99).time().'.'.$type; $new_file = $new_file.$picname; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){ return "/upload/".$picname; }else{ return false; } }else{ return false; } }
bootstrap-fileinput.css
/*! * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap) * Copyright 2012-2014 Arnold Daniels * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) */ .btn-file { position: relative; overflow: hidden; vertical-align: middle; } .btn-file > input { position: absolute; top: 0; right: 0; width: 100%; height: 100%; margin: 0; font-size: 23px; cursor: pointer; filter: alpha(opacity=0); opacity: 0; direction: ltr; } .fileinput { display: inline-block; margin-bottom: 9px; } .fileinput .form-control { display: inline-block; padding-top: 7px; padding-bottom: 5px; margin-bottom: 0; vertical-align: middle; cursor: text; } .fileinput .thumbnail { display: inline-block; margin-bottom: 5px; overflow: hidden; text-align: center; vertical-align: middle; } .fileinput .thumbnail > img { max-height: 100%; } .fileinput .btn { vertical-align: middle; } .fileinput-exists .fileinput-new, .fileinput-new .fileinput-exists { display: none; } .fileinput-inline .fileinput-controls { display: inline; } .fileinput-filename { display: inline-block; overflow: hidden; vertical-align: middle; } .form-control .fileinput-filename { vertical-align: bottom; } .fileinput.input-group { display: table; } .fileinput.input-group > * { position: relative; z-index: 2; } .fileinput.input-group > .btn-file { z-index: 1; } .fileinput-new.input-group .btn-file, .fileinput-new .input-group .btn-file { border-radius: 0 4px 4px 0; } .fileinput-new.input-group .btn-file.btn-xs, .fileinput-new .input-group .btn-file.btn-xs, .fileinput-new.input-group .btn-file.btn-sm, .fileinput-new .input-group .btn-file.btn-sm { border-radius: 0 3px 3px 0; } .fileinput-new.input-group .btn-file.btn-lg, .fileinput-new .input-group .btn-file.btn-lg { border-radius: 0 6px 6px 0; } .form-group.has-warning .fileinput .fileinput-preview { color: #8a6d3b; } .form-group.has-warning .fileinput .thumbnail { border-color: #faebcc; } .form-group.has-error .fileinput .fileinput-preview { color: #a94442; } .form-group.has-error .fileinput .thumbnail { border-color: #ebccd1; } .form-group.has-success .fileinput .fileinput-preview { color: #3c763d; } .form-group.has-success .fileinput .thumbnail { border-color: #d6e9c6; } .input-group-addon:not(:first-child) { border-left: 0; }
bootstrap-fileinput.js
/* =========================================================== * Bootstrap: fileinput.js v3.1.3 * http://jasny.github.com/bootstrap/javascript/#fileinput * =========================================================== * Copyright 2012-2014 Arnold Daniels * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ========================================================== */ +function ($) { "use strict"; var isIE = window.navigator.appName == 'Microsoft Internet Explorer' // FILEUPLOAD PUBLIC CLASS DEFINITION // ================================= var Fileinput = function (element, options) { this.$element = $(element) this.$input = this.$element.find(':file') if (this.$input.length === 0) return this.name = this.$input.attr('name') || options.name this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]') if (this.$hidden.length === 0) { this.$hidden = $('<input type="hidden">').insertBefore(this.$input) } this.$preview = this.$element.find('.fileinput-preview') var height = this.$preview.css('height') if (this.$preview.css('display') !== 'inline' && height !== '0px' && height !== 'none') { this.$preview.css('line-height', height) } this.original = { exists: this.$element.hasClass('fileinput-exists'), preview: this.$preview.html(), hiddenVal: this.$hidden.val() } this.listen() } Fileinput.prototype.listen = function() { this.$input.on('change.bs.fileinput', $.proxy(this.change, this)) $(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this)) this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this)) this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this)) }, Fileinput.prototype.change = function(e) { var files = e.target.files === undefined ? (e.target && e.target.value ? [{ name: e.target.value.replace(/^.+\\/, '')}] : []) : e.target.files e.stopPropagation() if (files.length === 0) { this.clear() return } this.$hidden.val('') this.$hidden.attr('name', '') this.$input.attr('name', this.name) var file = files[0] if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match(/^image\/(gif|png|jpeg)$/) : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") { var reader = new FileReader() var preview = this.$preview var element = this.$element reader.onload = function(re) { var $img = $("<img class='photo'>")//创建存储图片的img并给img添加一个class $img[0].src = re.target.result files[0].result = re.target.result element.find('.fileinput-filename').text(file.name) // if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account if (preview.css('max-height') != 'none') $img.css('max-height', parseInt(preview.css('max-height'), 10) - parseInt(preview.css('padding-top'), 10) - parseInt(preview.css('padding-bottom'), 10) - parseInt(preview.css('border-top'), 10) - parseInt(preview.css('border-bottom'), 10)) preview.html($img) element.addClass('fileinput-exists').removeClass('fileinput-new') element.trigger('change.bs.fileinput', files) } reader.readAsDataURL(file) } else { this.$element.find('.fileinput-filename').text(file.name) this.$preview.text(file.name) this.$element.addClass('fileinput-exists').removeClass('fileinput-new') this.$element.trigger('change.bs.fileinput') } }, Fileinput.prototype.clear = function(e) { if (e) e.preventDefault() this.$hidden.val('') this.$hidden.attr('name', this.name) this.$input.attr('name', '') //ie8+ doesn't support changing the value of input with type=file so clone instead if (isIE) { var inputClone = this.$input.clone(true); this.$input.after(inputClone); this.$input.remove(); this.$input = inputClone; } else { this.$input.val('') } this.$preview.html('') this.$element.find('.fileinput-filename').text('') this.$element.addClass('fileinput-new').removeClass('fileinput-exists') if (e !== undefined) { this.$input.trigger('change') this.$element.trigger('clear.bs.fileinput') } }, Fileinput.prototype.reset = function() { this.clear() this.$hidden.val(this.original.hiddenVal) this.$preview.html(this.original.preview) this.$element.find('.fileinput-filename').text('') if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new') else this.$element.addClass('fileinput-new').removeClass('fileinput-exists') this.$element.trigger('reset.bs.fileinput') }, Fileinput.prototype.trigger = function(e) { this.$input.trigger('click') e.preventDefault() } // FILEUPLOAD PLUGIN DEFINITION // =========================== var old = $.fn.fileinput $.fn.fileinput = function (options) { return this.each(function () { var $this = $(this), data = $this.data('bs.fileinput') if (!data) $this.data('bs.fileinput', (data = new Fileinput(this, options))) if (typeof options == 'string') data[options]() }) } $.fn.fileinput.Constructor = Fileinput // FILEINPUT NO CONFLICT // ==================== $.fn.fileinput.noConflict = function () { $.fn.fileinput = old return this } // FILEUPLOAD DATA-API // ================== $(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function (e) { var $this = $(this) if ($this.data('bs.fileinput')) return $this.fileinput($this.data()) var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]'); if ($target.length > 0) { e.preventDefault() $target.trigger('click.bs.fileinput') } }) }(window.jQuery);
二:多图上传预览并保存图片
index.html
<html> <head> <meta charset="UTF-8"> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script> </head> <style> .imgFile { width:500px; border:1px solid #dbdbdb; display:flow-root } @supports (display:flow-root) { .imgFile { display:flow-root; } }.imgFile label input { display:none } .imgFile label span { width:100px; height:100px; display:inline-block; border:1px solid #999999; margin:16px; position:relative } .imgFile label span:after { width:60%; height:1px; background:#dbdbdb; content:""; display:inline-block; position:absolute; top:50%; left:calc(50% - 30%) } .imgFile label span:before { width:1px; height:60%; background:#dbdbdb; content:""; display:inline-block; position:absolute; left:50%; top:calc(50% - 30%) } .imgFile .imgDiv { width:100px; height:100px; border:1px solid #999999; margin:16px; position:relative; float:left } .imgFile .imgDiv img { width:100%; height:100%; } .imgFile .imgDiv span { width:100%; height:20%; color:white; display:none; background:rgba(0,0,0,0.38); position:absolute; top:0; left:0; right:0 } .imgFile .imgDiv i { font-style:inherit; float:right; cursor:pointer; margin-right:5px; line-height:100%; font-size:20px } .imgFile .imgDiv:hover > span { display:block } .sub{ background:#147DD0; padding:10px 50px; border:none; margin-top:50px; color:white; } .sub:hover{ cursor:pointer; background:#094383; box-shadow:3px 3px 3px #888888; padding:10px 50px; border:none; margin-top:50px; color:white; } </style> <body> <div class="imgFile"> <label> <span></span> <input type="file" class="file"> </label> </div> <button class='sub' >提交</button> </body> <script> var imgs =[]; $(".file").change(function() { //获取图片信息 var fileLise = $(this)[0].files; var fileLength = fileLise.length; //然后循环 生成html 插入页面上 最后就赋值给img for (var i = 0; i < fileLength; i++) { var imgDiv = '<div class="imgDiv"><img id="img' + fileLise[i].name + '"><span><i class="imgRem">×</i></span></div>'; $(".imgFile").prepend(imgDiv); var imgName = document.getElementById("img" + fileLise[i].name); if (fileLise && fileLise[i]) { var file = new FileReader(); file.readAsDataURL(fileLise[i]); file.onload = function() { //console.log(this); imgs.push(this.result); imgName.src = this.result } } } }); $(".imgFile").on("click", ".imgRem", function() { $(this).parents(".imgDiv").remove(); }); //提交php $('.sub').click(function(){ $.post('index.php',{imgs:imgs},function(data) { console.log(data) },'json'); }) </script> </html>
index.php
<?php $arr=[]; foreach($_REQUEST['imgs'] as $k=>$v){ $url = base64_image_content($v,'upload'); array_push($arr,$url); } echo json_encode($arr); function base64_image_content($base64_image_content,$path){ //匹配出图片的格式 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){ $type = $result[2]; //$ff=date('Y-m-d',time()); $new_file = $_SERVER['DOCUMENT_ROOT'].'/'.$path.'/'; if(!file_exists($new_file)){ //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($new_file, 0700); } $picname=mt_rand(0,99).time().'.'.$type; $new_file = $new_file.$picname; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){ return "/upload/".$picname; }else{ return false; } }else{ return false; } }
三:简单js图片上传预览,php后端处理存文件夹,数据库 *文件同级目录建立upload文件夹
index.php(转)
<html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> .image_container { width: 48px; height: 48px; position: relative; } </style> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script language="javascript"> $(function() { $("#file_upload").change(function() { var $file = $(this); var fileObj = $file[0]; var windowURL = window.URL || window.webkitURL; var dataURL; var $img = $("#preview"); if(fileObj && fileObj.files && fileObj.files[0]){ dataURL = windowURL.createObjectURL(fileObj.files[0]); $img.attr('src',dataURL); }else{ dataURL = $file.val(); // $img.css("filter",'progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod = scale,src="' + dataURL + '")'); // var imgObj = document.getElementById("preview"); // imgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src=\"" + dataURL + "\")"; // imgObj.style.width = "48px"; // imgObj.style.height = "48px"; var imgObj = document.getElementById("preview"); // 两个坑: // 1、在设置filter属性时,元素必须已经存在在DOM树中,动态创建的Node,也需要在设置属性前加入到DOM中,先设置属性在加入,无效; // 2、src属性需要像下面的方式添加,上面的两种方式添加,无效; imgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)"; imgObj.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = dataURL; } }); }); </script> </head> <body> <form action='upload.php' method='post' enctype='multipart/form-data' id='form_add'> <div id="demo"> <input id="file_upload" type="file" name='img' /> <div class="image_container"> <img id="preview" width="60" height="60"> </div> </div> <br /> <button type='submit'>上传图片</button> </form> <br /> <div> <?php $con = mysqli_connect("localhost","root","root"); if(!$con){ die ( mysqli_error()); } mysqli_select_db($con,"test"); $sql="select * from img"; $result=mysqli_query($con,$sql); $row = mysqli_fetch_all($result); foreach($row as $v){ echo "<img style='margin-right:20px;width:50px;height:50px;' src = '".$v[1]."'/>"; } ?> </div> </body> </html>
upload.php
<?php header('Content-Type:text/html;charset=gb2312'); $con = mysqli_connect("localhost","root","root"); if(!$con){ die ( mysqli_error()); } mysqli_select_db($con,"test"); /*$sql="select * from img"; $result=mysqli_query($con,$sql); $row = mysqli_fetch_all($result); var_dump($row);die;*/ $uploadRoot = 'upload/';//设置上传目录 $files = $_FILES['img']; $fileName = $files['name']; $names = explode('.', $fileName); $newname = time().rand(1,10000).'.'.end($names); $fileSaved = $uploadRoot.$newname; $fileSaved = iconv("UTF-8", "GBK", $fileSaved); if(!move_uploaded_file($files['tmp_name'], $fileSaved)) { echo "图片保存失败!<a href='index.php'>返回首页</a>"; } else { $sql = "insert into img values('','".$fileSaved."')"; $result = mysqli_query($con,$sql); if($result){ echo "图片保存成功!<a href='index.php'>返回首页</a>"; }else{ echo "保存数据失败!<a href='index.php'>返回首页</a>"; } }
四:jquery.treeview.js 树状结构
index.php
<!DOCTYPE html pageEncoding="utf-8"> <html> <head> <title>treeview</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="treeview demo"> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <!-- 下载并导入 jquery.js | treeview.js | treeview.css--> <link rel="stylesheet" href="jquery.treeview.css" /> <script src="jquery.js" type="text/javascript"></script> <script src="jquery.treeview.js" type="text/javascript"></script> </head> <body> <ul id="tree" class="filetree"> <li><span class="folder">系统管理</span> <ul> <li><span class="folder">部门管理</span></li> <li><span class="folder">岗位管理</span> <ul> <li><span class="folder">岗位添加</span></li> <li><span class="folder">岗位删除</span></li> </ul> </li> <li><span class="folder">用户管理</span> <ul> <li><span class="folder">添加用户</span></li> <li><span class="folder">修改用户</span></li> </ul> </li> </ul> </li> <li> <span class="folder">审批流转</span> <ul> <li><span class="folder">岗位添加</span> <ul> <li><span class="folder">添加用户</span></li> <li><span class="folder">修改用户</span></li> </ul> </li> </ul> </li> </ul> <script type="text/javascript"> $("#tree").treeview({ persist: "location",//记忆折叠的方式。location,页面刷新不保留折叠状态;cookie,页面刷新保留折叠状态。 collapsed: true,//初始化时的折叠状态。true,初始化为收缩节点状态;false,与前相反。 unique: true//展开同级节点的唯一性。true,当展开一个节点时,同级的其他节点会自动关闭;false,当展开一个节点时,同级的其他节点保持原状态; }); </script> </body> </html>
jquery.treeview.css 需要修改,内部说明
.treeview, .treeview ul { padding: 0; margin: 0; list-style: none; } .treeview ul { background-color: white; margin-top: 4px; } .treeview .hitarea { background: url(images/treeview-default.gif) -64px -25px no-repeat; height: 16px; width: 16px; margin-left: -16px; float: left; cursor: pointer; } /* fix for IE6 */ * html .hitarea { display: inline; float:none; } .treeview li { margin: 0; padding: 3px 0pt 3px 16px; } .treeview a.selected { background-color: #eee; } #treecontrol { margin: 1em 0; display: none; } .treeview .hover { color: blue; cursor: pointer; } .treeview li { background: url(images/treeview-default-line.gif) 0 0 no-repeat; } .treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; } .treeview .expandable-hitarea { background-position: -80px -3px; } .treeview li.last { background-position: 0 -1766px } .treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); } .treeview li.lastCollapsable { background-position: 0 -111px } .treeview li.lastExpandable { background-position: -32px -67px } .treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; } .treeview-red li { background-image: url(images/treeview-red-line.gif); } .treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); } .treeview-black li { background-image: url(images/treeview-black-line.gif); } .treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); } .treeview-gray li { background-image: url(images/treeview-gray-line.gif); } .treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); } .treeview-famfamfam li { background-image: url(images/treeview-famfamfam-line.gif); } .treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); } .treeview .placeholder { background: url(images/ajax-loader.gif) 0 0 no-repeat; height: 16px; width: 16px; display: block; } /*folder.png为页面显示的小文件夹图片,需手动替换,附图片*/ .filetree li { padding: 3px 0 2px 16px;list-style-type:none; } .filetree span.folder, .filetree span.file { padding: 1px 0 1px 16px; display: block; } .filetree span.folder { background: url(folder.png) 0 3px no-repeat;text-indent:5px; } .filetree li.expandable span.folder { background: url(folder.png) 0 3px no-repeat;text-indent:5px; } .filetree span.file { background: url(folder.png) 0 3px no-repeat;text-indent:5px; }
jquery.treeview.js
/* * Treeview 1.4.2 - jQuery plugin to hide and show branches of a tree * * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ * * Copyright Jörn Zaefferer * Released under the MIT license: * http://www.opensource.org/licenses/mit-license.php */ ;(function($) { // TODO rewrite as a widget, removing all the extra plugins $.extend($.fn, { swapClass: function(c1, c2) { var c1Elements = this.filter('.' + c1); this.filter('.' + c2).removeClass(c2).addClass(c1); c1Elements.removeClass(c1).addClass(c2); return this; }, replaceClass: function(c1, c2) { return this.filter('.' + c1).removeClass(c1).addClass(c2).end(); }, hoverClass: function(className) { className = className || "hover"; return this.hover(function() { $(this).addClass(className); }, function() { $(this).removeClass(className); }); }, heightToggle: function(animated, callback) { animated ? this.animate({ height: "toggle" }, animated, callback) : this.each(function(){ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); if(callback) callback.apply(this, arguments); }); }, heightHide: function(animated, callback) { if (animated) { this.animate({ height: "hide" }, animated, callback); } else { this.hide(); if (callback) this.each(callback); } }, prepareBranches: function(settings) { if (!settings.prerendered) { // mark last tree items this.filter(":last-child:not(ul)").addClass(CLASSES.last); // collapse whole tree, or only those marked as closed, anyway except those marked as open this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide(); } // return all items with sublists return this.filter(":has(>ul)"); }, applyClasses: function(settings, toggler) { // TODO use event delegation this.filter(":has(>ul):not(:has(>a))").find(">span").unbind("click.treeview").bind("click.treeview", function(event) { // don't handle click events on children, eg. checkboxes if ( this == event.target ) toggler.apply($(this).next()); }).add( $("a", this) ).hoverClass(); if (!settings.prerendered) { // handle closed ones first this.filter(":has(>ul:hidden)") .addClass(CLASSES.expandable) .replaceClass(CLASSES.last, CLASSES.lastExpandable); // handle open ones this.not(":has(>ul:hidden)") .addClass(CLASSES.collapsable) .replaceClass(CLASSES.last, CLASSES.lastCollapsable); // create hitarea if not present var hitarea = this.find("div." + CLASSES.hitarea); if (!hitarea.length) hitarea = this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea); hitarea.removeClass().addClass(CLASSES.hitarea).each(function() { var classes = ""; $.each($(this).parent().attr("class").split(" "), function() { classes += this + "-hitarea "; }); $(this).addClass( classes ); }) } // apply event to hitarea this.find("div." + CLASSES.hitarea).click( toggler ); }, treeview: function(settings) { settings = $.extend({ cookieId: "treeview" }, settings); if ( settings.toggle ) { var callback = settings.toggle; settings.toggle = function() { return callback.apply($(this).parent()[0], arguments); }; } // factory for treecontroller function treeController(tree, control) { // factory for click handlers function handler(filter) { return function() { // reuse toggle event handler, applying the elements to toggle // start searching for all hitareas toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() { // for plain toggle, no filter is provided, otherwise we need to check the parent element return filter ? $(this).parent("." + filter).length : true; }) ); return false; }; } // click on first element to collapse tree $("a:eq(0)", control).click( handler(CLASSES.collapsable) ); // click on second to expand tree $("a:eq(1)", control).click( handler(CLASSES.expandable) ); // click on third to toggle tree $("a:eq(2)", control).click( handler() ); } // handle toggle event function toggler() { $(this) .parent() // swap classes for hitarea .find(">.hitarea") .swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ) .swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ) .end() // swap classes for parent li .swapClass( CLASSES.collapsable, CLASSES.expandable ) .swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ) // find child lists .find( ">ul" ) // toggle them .heightToggle( settings.animated, settings.toggle ); if ( settings.unique ) { $(this).parent() .siblings() // swap classes for hitarea .find(">.hitarea") .replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ) .replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ) .end() .replaceClass( CLASSES.collapsable, CLASSES.expandable ) .replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ) .find( ">ul" ) .heightHide( settings.animated, settings.toggle ); } } this.data("toggler", toggler); function serialize() { function binary(arg) { return arg ? 1 : 0; } var data = []; branches.each(function(i, e) { data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0; }); $.cookie(settings.cookieId, data.join(""), settings.cookieOptions ); } function deserialize() { var stored = $.cookie(settings.cookieId); if ( stored ) { var data = stored.split(""); branches.each(function(i, e) { $(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ](); }); } } // add treeview class to activate styles this.addClass("treeview"); // prepare branches and find all tree items with child lists var branches = this.find("li").prepareBranches(settings); switch(settings.persist) { case "cookie": var toggleCallback = settings.toggle; settings.toggle = function() { serialize(); if (toggleCallback) { toggleCallback.apply(this, arguments); } }; deserialize(); break; case "location": var current = this.find("a").filter(function() { return location.href.toLowerCase().indexOf(this.href.toLowerCase()) == 0; }); if ( current.length ) { // TODO update the open/closed classes var items = current.addClass("selected").parents("ul, li").add( current.next() ).show(); if (settings.prerendered) { // if prerendered is on, replicate the basic class swapping items.filter("li") .swapClass( CLASSES.collapsable, CLASSES.expandable ) .swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ) .find(">.hitarea") .swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ) .swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ); } } break; } branches.applyClasses(settings, toggler); // if control option is set, create the treecontroller and show it if ( settings.control ) { treeController(this, settings.control); $(settings.control).show(); } return this; } }); // classes used by the plugin // need to be styled via external stylesheet, see first example $.treeview = {}; var CLASSES = ($.treeview.classes = { open: "open", closed: "closed", expandable: "expandable", expandableHitarea: "expandable-hitarea", lastExpandableHitarea: "lastExpandable-hitarea", collapsable: "collapsable", collapsableHitarea: "collapsable-hitarea", lastCollapsableHitarea: "lastCollapsable-hitarea", lastCollapsable: "lastCollapsable", lastExpandable: "lastExpandable", last: "last", hitarea: "hitarea" }); })(jQuery);
folder.png
------------------