Bootstrap 3 – custom menu, fixed bottom, header, back to top

В програмирането има едно правило, което перефразирано гласи да не търсиш топлата вода всеки път. За това качвам няколко базови кода за Bootstrap 3, които съм писал или копирал и променял. Помогнал съм си леко с Less за някои стилове.

Custom menu
Нищо ново. Добавено е само малко CSS-кодиране на менюто, което се предлага стандартно с Bootstrap.

Bootstrap 3- custom menu

Bootstrap 3- custom menu

Демо

Header
Напаснал съм отделните слоеве с помощта на Boostrap стиловете col-*-push и col-*-pull, така че да има приличен респонзив.

Bootstrap 3- header

Bootstrap 3- header

Bootstrap 3- header

Демо

Fixed bottom
Фиксиран фуутер за мобилни устройства – особено полезно при писане на мобилно приложение, базирано на HTML.

Bootstrap 3- fixed bottom

Bootstrap 3- fixed bottom

Демо

Back to top бутон
Клиентите често искат подобна опция. Кода е няколко реда и има и малко JavaScript, освен CSS-а.

Bootstrap 3- back to top

Демо

Допълнително в архива съм добавил и Bootstrap 3 – login form.

Изтегляне на кода: header_menu_fixed-bottom_back-to-top_login-form.zip

===============
Добавям и още 2 вертикални менюта

Bootstrap 3 – Drop Down menu – only CSS
Bootstrap 3 - CSS Drop Down menu - CSS_only
Демо
Изтегляне

Bootstrap 3 – Drop Down menu – CSS and JavaScript
Bootstrap 3 - CSS Drop Down menu - CSS and JS
Демо
Изтегляне

Bootstrap 3 – Login form

Bootstrap 3 - Login Form
От известно време се каня да променя логин формата за админ панела на проектите, които правя. Направих една форма, която не знам дали ще ползвам, но ще ми е полезна като отправна точка. За да си помогна за стиловете използвах Less (език за стилови множества или CSS) и GUI-то SimpLESS – портабъл е и работи доста леко за разлика от други подобни.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 		MIXINS
//  ==========================================
.rounded-corners (@radius1: 5px, @radius2: 5px, @radius3: 5px, @radius4: 5px) { 
	-webkit-border-radius: @radius1 @radius2 @radius3 @radius4; 
	-moz-border-radius: @radius1 @radius2 @radius3 @radius4; 
	-ms-border-radius: @radius1 @radius2 @radius3 @radius4; 
	-o-border-radius: @radius1 @radius2 @radius3 @radius4; 
	border-radius: @radius1 @radius2 @radius3 @radius4; 
}
 
.drop-shadow (@x: 0, @y: 1px, @blur: 2px, @spread: 0, @alpha: 0.25) {
	-webkit-box-shadow:	@x @y @blur @spread rgba(0, 0, 0, @alpha);
	-moz-box-shadow:	@x @y @blur @spread rgba(0, 0, 0, @alpha);
	box-shadow:		@x @y @blur @spread rgba(0, 0, 0, @alpha);
}
 
.gradient (@startColor: #eee, @endColor: white) {
	background-color: @startColor;
	background: -webkit-gradient(linear, left top, left bottom, from(@startColor), to(@endColor));
	background: -webkit-linear-gradient(top, @startColor, @endColor);
	background: -moz-linear-gradient(top, @startColor, @endColor);
	background: -ms-linear-gradient(top, @startColor, @endColor);
	background: -o-linear-gradient(top, @startColor, @endColor);
}
 
 
 
// 		Colors
//  ==========================================
@silver_light: #edf1f2;
@silver_white: #f7f8fa;
@silver_dark: #eef7fc;
@silver_border: #c3d5d9;
@grey: #8f8f8f;
@blue_dark: #76ccea;
@blue_light: #badff2;
 
 
// 		Styles
//  ==========================================
body {
	background-color: @silver_light;
}
 
.container.lf{
	width: 322px;
	color: @grey;
	a {color: @grey;}
 
		.logf {
			margin-top: 50px;
			.rounded-corners(5px, 5px, 5px, 5px);
			.drop-shadow(0px, 0px, 6px, 2px, 0.05);
		}
 
		.lfhead, .lfbody, .lffooter{
			border: 1px solid @silver_border;
			background-color: @silver_white;
			min-height: 20px;
			// line-height: 15px;
		}
 
		.lfhead {
			border-bottom: 0;
			.rounded-corners(5px, 5px, 0, 0);
		}
 
		.lfbody {
			border-top: 0;
			border-bottom: 0;
 
			.input-group-addon {
				color: @grey;
			}
			 .form-control:focus {
			 	.drop-shadow(0px, 0px, 6px, 2px, 0.05);
			 	border-color: @blue_dark;
			 }
		}
 
		.lffooter {
			background-color: @silver_dark;
			.rounded-corners(0, 0, 5px, 5px);
			padding-top: 16px;
 
			.text-left {
				padding-top: 8px;
			}
 
			label {
				font-weight: normal;
				color: @grey;
			}
 
			input[type='button'], input[type='reset'], input[type='submit'] {
				.rounded-corners(18px, 18px, 18px, 18px);
				border-color: @blue_dark;
				.gradient(@blue_light, @blue_dark);
				font-weight: bold;
				.drop-shadow(0px, 1px, 2px, 1px, 0.10);
				text-shadow: 1px 1px @blue_dark;
 
				&:hover {
					.gradient(@blue_dark, @blue_light);
				}
			}
		}
 
	.lflinks {
		padding-top: 8px;
	}
 
}

HTML кода:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<div class="container lf">
   <div class="row logf text-center">
      <form action="" method="post" >
         <div class="col-xs-12 lfhead">
         </div>
         <div class="col-xs-12 lfbody">
            <div class="form-group">
               <div class="input-group">
                  <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                  <input id="email" type="email" class="form-control" name="email" value="" tabindex="1" placeholder="Email Address">
               </div>
            </div>
            <div class="form-group">
               <div class="input-group">
                  <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                  <input id="password" type="password" class="form-control" name="password" value="" tabindex="2" placeholder="Password">                    
               </div>
            </div>
         </div>
         <div class="col-xs-12 lffooter">
            <div class="col-xs-6">
               <div class="form-group text-left">
                  <input type="checkbox" tabindex="3" class="" name="remember" id="remember">
                  <label for="remember"> Remember Me</label>
               </div>
            </div>
            <div class="col-xs-6">
               <div class="form-group text-right">
                  <input type="submit" name="login-submit" tabindex="4" class="btn btn-primary" value="Login">
               </div>
            </div>
         </div>
      </form>
   </div>
   <div class="row lflinks">
      <div class="col-xs-6 text-left"><a href="">Register</a></div>
      <div class="col-xs-6 text-right"><a href="">Forgot password</a></div>
   </div>
</div>

Останалото форматиране си идва от Bootstrap 3.
Демо на страницата: BS3 Login Form
Download: bs3-login_form.zip

Bootstrap 3 dropdown login form example

Търсих си неразкрасена логин форма за Bootstrap 3. Трябваше да я набутам в бутон на на nav-панела. Не намерих нищо свястно, ам тя работата е елементарна. Ще покажа 2 различни примера.
Bootstrap login form - dropdown, popover
BS3 Login form с popover и html код разположен някъде в страницата:
Javascript – поставя се най-долу в кода на страницата

1
2
3
4
5
6
7
$('button[data-toggle=popover]').popover({ 
    html : true,
    //trigger: "click", // може да се смени
    content: function() {
      return $('#popover_content_wrapper').html();
    }
});

HTML-кода:

1
2
3
4
5
6
7
8
9
10
11
12
<div id="popover_content_wrapper" style="display: none">
  <form action="" role="form">
    <div class="form-group">
      <label for="user">User</label>
      <input type="text" class="form-control" id="user" placeholder="User" />
      <label for="password">Password</label>
      <input type="password" class="form-control" id="password" placeholder="Password" />
    </div>
      <button type="submit" class="btn btn-default">Sign in</button>
 
  </form>
</div>

BS3 Login form с dropdown:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<li>
 
  <div class="dropdown">
    <button type="button" class="btn btn-default navbar-btn" data-toggle="dropdown">Login</button>
 
    <div class="dropdown-menu" style="padding: 10px; background: #ddd">
      <form action="" role="form">
        <div class="form-group">
          <label for="user">User</label>
          <input type="text" class="form-control" id="user" placeholder="User" />
          <label for="password">Password</label>
          <input type="password" class="form-control" id="password" placeholder="Password" />
        </div>
        <button type="submit" class="btn btn-default">Sign in</button>
      </form>
    </div>
  </div>
 
</li>

Пример с 2-те форми може да се види тук:
Bootstrap 3 dropdown login form example

CSS – Attribute Selectors

CSS – Attribute Selectors

CSS разполага с няколко “странни” символа, които в други езици са известни като wildcards. Тези символи представляват селектори на текст и могат да съвпадат с части от текста.

  • [att^=val] – започва с “val”
  • [att$=val] – завършва с “val”
  • [att*=val] – съдържа “val”

Атрибут селекторите могат да се използват за всякакви атрибути на таговете, като класове (.class1, class2…) или идентификатори(#id1, id2…), href, title, name и т.н.

Примери за прилагане на стилове с атрибут селектора “започва с”:
begin with css selector
The “begins with” CSS selector – DEMO

Примери за прилагане на стилове с атрибут селектора “завършва с”:
ends with css selector
The “ends with” CSS selector – DEMO

Примери за прилагане на стилове с атрибут селектора “съдържа”:
contains css selector
The “contains” CSS selector – DEMO

Simple JavaScript rich text format editor

Прост, базов RTF редактор за сайт
JS_WisWyg_Editor_by_Ned
Дълго съм се чудил кой е най-подходящия JavaScript Wysiwyg редактор с най-много възможности за напасване към сайт. Ползвал съм NicEdit, TinyMCE и други, които сам съм писал, неподдържащи rich text format (RTF). Обаче напасването на тези редактори към различни дизайни е развибащо от към бачкане и тестване в различните браузери. Реших да почопля няколко такива редактора и да разбера кое е толкова загадъчно и сложно, за да се напише подобен редактор. Истината е тривиална и се казва – iFrame. Този таг се ползва в почти всички подобни редактори, точно заради поддръжката му на RTF. При събмитване на формата, цялото съдържание на iform се подава на textarea, който си седи удобно скрит.

Това е моят редактор, без CSS-форматиране, като в примера добавям и опция за обработка на текста от базата данни, където присъства без тагове, с ексейпнати малко по-рискови символи.

<?php
$field = '<a href="aloooha">Test\'ed. kavicha</a> dyra, byra.<br />Още текст и още "кирилица".';
$clearpost = $field;
 
 
if(isset($_POST['button'])){
	echo $_POST['myTextArea'];
	$clearpost = $_POST['myTextArea'];
}
 
//$clearpost = preg_replace('@delete|select|insert|update|where@i',"", $clearpost); // Почистване на 
//$clearpost = preg_replace('/[\x7f-\xff]/', "", $clearpost); // Clear Dirty Data
$clearpost = preg_replace("/;/", "&#59;", $clearpost);
$clearpost = preg_replace("/\*/", "&#42;", $clearpost);
$clearpost = preg_replace("/\r\n/", "<br />", $clearpost);
$clearpost = preg_replace("/\r/", "<br />", $clearpost);
$clearpost = preg_replace("/\n/", "<br />", $clearpost);
$clearpost = preg_replace("/</", "&lt;", $clearpost);
$clearpost = preg_replace("/=/", "&#61;", $clearpost);
$clearpost = preg_replace("/>/", "&gt;", $clearpost);
$clearpost = preg_replace("/\'/", "&#39;", $clearpost);
$clearpost = preg_replace("/\`/", "&#96;", $clearpost);
$clearpost = preg_replace("/\"/", "&quot;", $clearpost);
 
if (!get_magic_quotes_gpc()) $clearpost = preg_replace('@\\\@', "&#92;", $clearpost);
else {
	$clearpost = stripslashes($clearpost);
	$clearpost = preg_replace('@\\\@', "&#92;", $clearpost);
}
 
 
$clearpost = preg_replace("/&#39;/", "\&#39;", $clearpost); // Ескейпване на единичната кавичка, за да може да се показва в iframe!!!
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1251" /> 
<script src="wiswyg_ned/nedEditor.js"></script>
<script type="text/javascript">
 
window.onload=function(){
	iFrameOn();
	if(isIE){
		var myFrame = document.getElementById('richTextField');
		var frameDoc = myFrame.contentDocument || myFrame.contentWindow;
 
		if (frameDoc.document){
		  frameDoc = frameDoc.document;
		}
		frameDoc.write ('<?php echo html_entity_decode($clearpost, ENT_QUOTES); ?>') ;
	} else {
		window.frames['richTextField'].document.body.innerHTML = '<?php echo html_entity_decode($clearpost, ENT_QUOTES); ?>' ;
	}
}
</script>
</head>
<!-- <body onLoad="iFrameOn();" > -->
<body>
<form action="" enctype="multipart/form-data" name="myForm" id="myform" method="post">
<div id="wysiwyg_cp" style="padding:8px; width:700px;">
	<input type="button" onClick="iBold()" value="B"> 
	<input type="button" onClick="iUnderline()" value="U">
	<input type="button" onClick="iItalic()" value="I">
	<input type="button" onClick="iFontSize()" value="Text Size">
	<input type="button" onClick="iForeColor()" value="Text Color">
	<input type="button" onClick="iHorizontalRule()" value="HR">
	<input type="button" onClick="iUnorderedList()" value="UL"><br />
	<input type="button" onClick="iOrderedList()" value="OL">
	<input type="button" onClick="iLink()" value="Link">
	<input type="button" onClick="iUnLink()" value="UnLink">
	<input type="button" onClick="iImage()" value="Image">
	<input type="button" onClick="iRemoveFormat()" value="Remove Format"> 
</div>
	<!-- Hide(but keep)your normal textarea and place in the iFrame replacement for it -->
	<textarea style="display:none;" name="myTextArea" id="myTextArea" cols="100" rows="14"></textarea>
 
	<iframe name="richTextField" id="richTextField" ></iframe>
	<br />
	<input type="submit" name="button" id="button" value="Make Changes" onClick="javascript:submit_form();"/>
</form>
</body>
</html>

Съдръжанието на JavaScript файла:

// Check Browser
var isOpera = !!(window.opera && window.opera.version);  // Opera 8.0+
var isFirefox = testCSS('MozBoxSizing');                 // FF 0.8+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
    // At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !isSafari && testCSS('WebkitTransform');  // Chrome 1+
var isIE = /*@cc_on!@*/false || testCSS('msTransform');  // At least IE6
 
function testCSS(prop) {
    return prop in document.documentElement.style;
}
//====================
 
 
function iFrameOn(){ 
    richTextField.document.designMode = 'On';
    //window.frames['richTextField'].document.body.innerHTML = '<a href="aloooha">Aloha</a> dyra, byra.<br />Още текст има тук.';	
}
function iRemoveFormat(){
    richTextField.document.execCommand('removeformat',false,null); 
}
function iBold(){
    richTextField.document.execCommand('bold',false,null); 
}
function iUnderline(){
    richTextField.document.execCommand('underline',false,null);
}
function iItalic(){
    richTextField.document.execCommand('italic',false,null); 
}
function iFontSize(){
    var size = prompt('Enter a size 1 - 7', '');
    richTextField.document.execCommand('FontSize',false,size);
}
function iForeColor(){
    var color = prompt('Define a basic color or apply a hexadecimal color code for advanced colors:', '');
    richTextField.document.execCommand('ForeColor',false,color);
}
function iHorizontalRule(){
    richTextField.document.execCommand('inserthorizontalrule',false,null);
}
function iUnorderedList(){
    richTextField.document.execCommand("InsertOrderedList", false,"newOL");
}
function iOrderedList(){
    richTextField.document.execCommand("InsertUnorderedList", false,"newUL");
}
function iLink(){
    var linkURL = prompt("Enter the URL for this link:", "http://"); 
    richTextField.document.execCommand("CreateLink", false, linkURL);
}
function iUnLink(){
    richTextField.document.execCommand("Unlink", false, null);
}
function iImage(){
    var imgSrc = prompt('Enter image location', '');
    if(imgSrc != null){
        richTextField.document.execCommand('insertimage', false, imgSrc); 
    }
}
function submit_form(){
    var theForm = document.getElementById("myform");
    theForm.elements["myTextArea"].value = window.frames['richTextField'].document.body.innerHTML;
    theForm.submit();
}

Сорс кода: wiswyg_by_ned.rar
Demo нa кода.

Нова версия на BGHotelCMS

Най-накрая намерих малко време да обновя проекта си, с който искам да подпомогна българския туризъм – BGHotelCMS 1.01.
Кода го пренаписах от нулата, като използвах PHP MiniTemplator, за да разделя програмирането от дизайна. Това ми помогна да съкратя доста кодирането и ми позволява да създавам и добавям много лесно нови теми за дизайна.

Повече подробности за този проект могат да се видят на страницата му – http://bghotelcms.nediko.info/

Web Mechanize engines

Съществуват много приложение на ботовете за автоматизиране на web-среда, т. нар. Web Mechanize engines. Тук ще разгледам няколко такива системи за механизиране и автоматизиране на работата с web-страници.

Приложение на Mechanize-ботовете

С помощта на скриптовете за автоматизиране на Web могат да се:

  • Попълват множество бланки и формуляри с еднородна информация
  • Търси в мрежата
  • Автоматизират регистрации. Примерно автоматизирано попълване на бланки за Гражданска отговорност.
  • Извличане на информация от множество сайтове наведнъж и съхраняването и.

и т.н.

Някои по-популярни Mechanize системи

WWW::Mechanize – Perl модул, написан от Jesse Vincent. Един от първите подобни модули за автоматизирано браузване.
mechanize – Python алтернатива на по-горния модул. Включва достъпните (супер лесни за работа даже) mechanize.Browser и mechanize.UserAgentBase имплементации на urllib2.OpenerDirector.
LWP – The World-Wide Web библиотека отново за Perl.
twill – базиран на Python изключително прост език за автоматизирано браузване. Изпълнява се от команден ред и изисква Python 2.3 или по-нов.
zope.testbrowser – още един модул за Python.
Watir – библиотека на Ruby за автоматизирано браузване. Супер лесна за работа.
Scriptable Browser – PHP алтернатива на горните модули. Все още има какво да се желае, но определено доста интересен проект.
Snoopy – PHP клас, който също е насочен към автоматизирано браузване.
Compass_Mechanize – PHP пакет, който е наречен от авторите “WWW::Mechanize for PHP”. Изисква Zend Framework.

Firefox Mechanize extensions

Освен посочените по-горе модули или езици, съществуват и приложения, които работят в средата на браузъра. Ще посоча някои механизатори за Firefox:
iMacros – Един от най-яките автоматизатори. Записва всички събития и генерира изключително лек и четим код. Не е нужно да изучвате скриптов език. Супер елементарно се работи с тази добавка.
iMacros Command Line – това брилянтно разширение разполага и с поддръжка на командния ред.
Chickenfoot – много любим механизатор. Има си собствен език за писане на скриптовете, който е доста лесен. Разполага и с рекордер на събитията, както и старт от командния ред: firefox -cf-run.
DejaClick – още една добавка за Firefox, която може да записва събития. Генерира малко трудно-четими скриптове, иначе пък си има някои полезни опции.
Selenium IDE – един от първите автоматизиращи плъгини за Firefox. Помня, че четох за него преди поне 6-7 години, дет се вика от зората на пандата. Не съм го ползвал, защото тогава не ми е бил необходим, но определено заслужава да е в този списък.

Разбира се има и много стари и достъпни методи за автоматизиране на по-леки задачи в Web. Например с cURL и wget понякога могат да се постигнат чудеса.