When we recently decided to redesign our website, we came across the issue of keeping the visitors flow from our old pages and links. As best practice for SEO, we had to redirect our old links to the new ones. The obvious decision was to simply use “Redirect 301” in our .htaccess, but that messed up our subdomains.

Apache

1

Redirect301^/index\.php$/index.html#this would usually do, but not in this case

After some research it became clear that the answer was mod_rewrite (for those of you not familiar with this practice, here is a useful article about url rewriting). The trick was to use a rewrite condition for your root domain, so that the redirection applies only to it.

Apache

1

2

3

4

RewriteEngineon

RewriteCond%{HTTP_HOST}^(www\.)?if-act\.net$[NC]#this is the condition

RewriteRule^/index\.php$/index.html[R=301,NE,L]#this applies if the condition is true

RewriteRule^/contacts\.php$/#contacts [R=301,NE,L] #redirection to an anchor

So the “RewriteCond” compares %{HTTP_HOST} variable (for the php gurus out there %{VAR} variables correspond to php $_SERVER[‘VAR’] variables) and redirects only if true. It is important to pay attention to the flags after the rewrite rule. The “R=301” flag states that this is a permanent redirection (best practice for SEO) and the “L” flag tells the server that it shouldn’t look at any other rules after this one. Also essential when dealing with hashes in the redirecition process is to use the “NE” flag, which tells the server not to escape special chars.

It is also important to look at the case when you want to redirect a link with a query portion (that’s the string after the query sign – ‘?’) to another with hash (‘#’) in it. As the server doesn’t take notice of the query portion it will simply append it to the new URL.

The airport departure board effect is now available for everybody to use

If you need a new and cool effect for your website you need not to look for such anymore. The split flap display plugin for JQuery gives you the ability to turn every string into an amazing eye-catching animation as you may have seen on an airport departure board.

It’s very simple to use

You need only to include the jquery library and the plugin file called splitFlap.js

Invoke the plugin on any HTML DOM object with proper innerHTML (text only).

1

2

3

4

5

<script type="text/javascript">

$(document).ready(function(){

$('p').flapDisplay();

});

</script>

Starting the animation goes like this:

1

2

3

4

5

6

7

<script type="text/javascript">

$(document).ready(function(){

$('p').flapDisplay();

$('p').flapDisplay('start');

});

</script>

The plugin has two modes of operation. The default mode uses the textual content of the object given to the plugin and implements the airport departure board effect on it. The second mode uses an array of words passed to it for a more genuine split-flap display recreation. More detailed information about all the options and setting is available at the end of this article.

The JQuery plugin is prepared for almost anything you could want of it

Let’s look at some examples:

The common regular flip implemented on hover:

Just place the mouse in a cell and watch what happens

The delayed flip implemented on hover:

With this settings the chars start to flip gradually in contrast to the default settings where they all start together.

More realistic airport departure board:

In this example I’ve passed an array of words. You can see the result for yourself. As you can see it copes very well with special chars and different alphabets.

On-demand flip:

You could pass words to the plugin dynamically.

Plugin documentation

Settings:

delayed: [boolean]

Description: Controls whether the animation starts with all chars flipping together (delayed: false) or they are gradually included to the flipping process (delayed: true)Default value: false

chars: [string]

Description: A string which specifies the chars that are to be used in the flipping process. In case you’ve missed a char that appears in some of the innerHTMLs the plugin will automatically detect and add it. Parsing less chars will result in a faster animation.Default value: ‘$_!@#%()-12357890abcdefghijklmnopqrstuvwxyz ‘

words: [Array]

Description: Parse here an array of words for the plugin to use.Default value: []

speed: [integer]

Description: Given in milliseconds this is the speed at which the plugin refreshes the string while flipping. Smaller number will result in a faster animation.Default value: 70

interval: [integer]

Description: Given in milliseconds this is the pause time between words. If there are no words passed this parameter is obsolete Default value: 2000

Finally, the new and improved version of our Drag’n’Slide gallery is out. Following the latest trends in gallery design, we’ve added some new features to our product, while preserving the unique properties of the plugin. Below you may find some code samples, as well as a demo of the gallery.

What’s new?

Cool navigation added!

As you will see the new Drag’n’Slide jQuery gallery will provide the user with a simple and intuitive way of navigating across the pictures in the gallery. These tiny and cool circles will fit perfectly into any website design.

Changeable background colour!

For perfect compatibility with every website layout You can now choose the background colour that will enable the Drag’n’Slide jQuery gallery to fit right into your design.

Border on/off!

Outline the Drag’n’Slide jQuery gallery with a sleek border or just allow it to blend with the rest of the webpage.

You can find detailed documentation of the new features of the Drag’n’Slide Jquery Gallery below.

How to use Drag and Slide JQuery gallery?

Simple and easy to use

Just wrap your content with a single div and call the gallery on it. The code will look like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.

.

.

<script type="text/javascript">

$("#your_div_ID").drag_n_slide_gallery();

</script>

.

.

.

<div id="your_div_ID">

<img/>

.

.

.

<img/>

</div>

Drag and slide website content

If you wish to store additional HTML information inside each draggable entity, then you should wrap all the entities with the .page CSS class.

Available settings:

New features

border: {string}

backgroundColor: {string}

Description: Choose the right background color that would fill the empty space in the gallery if a picture is too small or the color that will appear behind Your content if You use the Drag’n’Slide JQuery Gallery in page mode.Default value: ‘#383838’Example: backgroundColor: ‘#FFFFFF’ or backgroundColor: ‘lightgreen’

Legacy settings: v1.0

width: {value} or ‘{value}px’

Description: Width of each gallery’s page/image. The width is applied only to images, whose own width is bigger than the the one described here.Default value: ‘640px’Example: width: 600 or width: ‘600px’

coefficient: 0 <= {value} < 1

Description: The coefficient of the offset needed in order for the image to be moved. If – for example – it is set to 0.2 (20%), the user would need to move current image/page 0.2 times of the whole width (see above) in order to see the next one. When instantMove property (see below) is set to true, the coefficient is overridden – its value won’t matter.Default value: 0.4Example: coefficient: 0.2

instantMove: {boolean}

Description: If set to true the image/page is directly moved after the first drag. If – for example – it is set to false (the default value), an image/page could be only moved when the user clicks on it, moves the mouse and releases it. If – on the other hand – the property is set to true, the only thing the user needs to do is to click on the image/page and moves the mouse horizontally – no release of the mouse button is needed.Default value: falseExample: instantMove: true

verticalCenter: {boolean}

Description: Centers image (resp. – page’s content) vertically when the display’s height is bigger than the one of the object inside it.Default value: falseExample: verticalCenter: true

initialTip: {boolean}

Description: A fast sliding effect of all the images/pages intended to show the user that the image (resp. – page contents) is draggable.Default value: falseExample: initialTip: true

We are glad to introduce ver1.0 of our Drag’n’Slide gallery. Below you may find some code samples, as well as a demo of the gallery. A modified version, used to present some content along with the images, is used in our portfolio.

How to use Drag and Slide gallery?

Simple and easy to use

Just wrap your content with a single div and call the gallery on it. The code will look like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.

.

.

<script type="text/javascript">

$("#your_div_ID").if_act_gallery();

</script>

.

.

.

<div id="your_div_ID">

<img/>

.

.

.

<img/>

</div>

Drag and slide website content

If you wish to store additional HTML information inside each draggable entity, then you should wrap all the entities with the .page CSS class.

Available settings:

width: {value} or ‘{value}px’

Description: Width of each gallery’s page/image. The width is applied only to images, whose own width is bigger than the the one described here.Default value: ‘640px’Example: width: 600 or width: ‘600px’

coefficient: 0 <= {value} < 1

Description: The coefficient of the offset needed in order for the image to be moved. If – for example – it is set to 0.2 (20%), the user would need to move current image/page 0.2 times of the whole width (see above) in order to see the next one. When instantMove property (see below) is set to true, the coefficient is overridden – its value won’t matter.Default value: 0.4Example: coefficient: 0.2

instantMove: {boolean}

Description: If set to true the image/page is directly moved after the first drag. If – for example – it is set to false (the default value), an image/page could be only moved when the user clicks on it, moves the mouse and releases it. If – on the other hand – the property is set to true, the only thing the user needs to do is to click on the image/page and moves the mouse horizontally – no release of the mouse button is needed.Default value: falseExample: instantMove: true

verticalCenter: {boolean}

Description: Centers image (resp. – page’s content) vertically when the display’s height is bigger than the one of the object inside it.Default value: falseExample: verticalCenter: true

initialTip: {boolean}

Description: A fast sliding effect of all the images/pages intended to show the user that the image (resp. – page contents) is draggable.Default value: falseExample: initialTip: true

Free Search engine optimization – SEO tool for Google

Tired of scrolling down and checking all the results in Google for your webpage or website? I present you the website position checker for Google. A free SEO tool that will show you at which position does your website appear in Google’s results for the keywords that you need. Just fill out the form and find out the position of you site in Google.

At your attention is a simple tutorial about building a javascript calculator using jQuery. The whole code is explained below and a demo of the calculator is available here: calculator demo.

As I think the markup and the styling are self-explanatory, they would not be shown here explicitly, so let’s start with the code.
First we declare a few variables, half of them pointing to HTML elements.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

$('document').ready(function(){

var$calc=$("#calculator");

var$display=$("#display");

var$digits=$(".digits");

var$operations=$(".operations");

varinit=0;

varoperand=init;

varoperation=null;

varafterOperation=false;

varreset=function(){

$display.text(init);

operand=null;

operation=null;

};

$calc points to the calculator body, but I am pretty sure it has actually never been used through the code.$display points at – of course – the calculator display (a div element), while $digits and $operations are sets representing the digits and operations DIVs respectively. The init variable is used by initializing the calculator and resetting the state – of course, it is 0. What operand point to is the first of two operands, taking part in each operation. The operation variable is used to hold the last unexecuted operation, chosen by the user. The afterOperation flag indicates whether the last user’s choice was a digit or an operation. The reset variable, pointing to an anonymous function, resets the display and both operand and operation, used through the code below.

The remaining part of the code is actually a few click handlers – for clicking on a digit or a operation button and two additional – for the decimal point (which I, should admit, wrongly call ‘dot’) and for the change of the sign (+/-). The first function, which comes after the variable declaration and initialization is the digit click handler.

1

2

3

4

5

6

7

8

9

10

11

12

13

$digits.not($('#dot, #sign')).click(function(event){

event.preventDefault();

if(afterOperation==false){

if($display.text()==init&&$display.text().indexOf('.')<0){

$display.text($(this).text());

}else{

$display.append($(this).text());

}

}else{

$display.text($(this).text());

afterOperation=false;

}

});

First, as you can see, I exclude the dot and the sign buttons from the elements set, as they actually belong to the digits class, but should be handled a bit differently.
Here the afterOperation flag is used for the first time – there are two options, depending on the flag value – the first one (if (afterOperation == false) {…) is used when we are ‘building’ the value digit by digit and the second one is used to start ‘building’ the value after an operation has been performed. The main difference is in the text() and append() functions – the first one types the clicked digit ($(this).text()) in the display, while the second one simply concatenates the digit to these, already present in the display.
By afterOperation with a value of false, there are analogically two cases – the first one (if ($display.text() == init && $display.text().indexOf(‘.’)<0) {...) checks whether the display has the init value (0) AND whether NO decimal point is available. In this case the text() function is used – that means that the newly chosen digit is written in the display on the init value’s place. The reason to check for the absence of the decimal point, is the following – when we have for example 0 on the display and click the ‘dot’ button for adding a decimal point, the point is concatenated to the zero. However, the expression “0.” == 0 evaluates to true and so the text() function would be invoked, while we need to append digits after the decimal point – so the $display.text().indexOf(‘.’)<0 statement has been added. So in the case “0.” we have true for the first statement $display.text() == init and false for the second one, thus eventually having true AND false, which evaluates to false, making the code appending digits after the dot instead of not resetting the display with the text() function.
Let’s now have a look at the operation handler.

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

$operations.click(function(event){

event.preventDefault();

varcurrOperation=$(this).text();

varcurrOperand=parseFloat($display.text());

if(currOperation!='CE'){

// Do the math

if(operation!=null&&!afterOperation){

switch(operation){

case'+':{

$display.text(operand+currOperand);

break;

}

case'-':{

$display.text(operand-currOperand);

break;

}

case'*':{

$display.text(operand *currOperand);

break;

}

case'/':{

if(currOperand!=0){

$display.text(operand/currOperand);

}else{

alert("What the fuck?!");

reset();

}

break;

}

}

}

if(currOperation!='='){

operation=currOperation;

}else{

operation=null;

afterOperation=false;

return;

}

operand=parseFloat($display.text());

afterOperation=true;

}else{

reset();

}

});

First, we make two additional local variables – currOperation for the current operation and currOperand for the current operand. Then we simply check if the Clear button is pressed – if so, we call the reset() function.
If not, however, we go on with the math.
First, we check if there is already an operation set AND whether the flag afterOperation has a value of false, which means that no operation button has been clicked just before the event, being handled at the moment. If both the upper conditions are satisfied, a switch statement (for the operation, not currOperation) takes care for doing the math. Please note that if we have typed a value (e.g. 5) for example, than chosen ‘+’ operation, type a value again and chose a ‘-‘ operation, the operation variable would point to the last unhandled one – that means the plus operation, so it would be caught and executed by the switch statement. So, at the moment of clicking on the minus sign, the plus operation would be executed.
The expression if (currOperation != ‘=’) {operation = currOperation;} takes care of assigning the current and still not executed operation (the ‘minus’ from the example above) to the operation variable. The operation behind the equal sign is, of course, not to be remembered anywhere – by clicking on the equal sign, we execute the last available operation and reset the operation and the afterOperation flag.
However, no matter how many times we have clicked on an operation button (different from “CE” and “=”),

1

2

3

4

...

operand=parseFloat($display.text())

afterOperation=true;

...

statements would be executed – operand should point to the value, currently available on the display (that is – most likely – the result of the past operation) and afterOperation should be true.
The last two handlers are for the decimal point and the switch sign.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

$('#dot').click(function(event){

event.preventDefault();

if(!afterOperation){

if($display.text().indexOf('.')<0){

$display.append('.');

}

}else{

$display.text('0.');

afterOperation=false;

}

});

$("#sign").click(function(event){

event.preventDefault();

if(afterOperation){

return;

}else{

$display.text(parseFloat($display.text())*(-1));

afterOperation=true;

}

});

The ‘dot’ click handler appends a single dot to the digits available in the display if afterOperation flag is false or writes “0.” string in the display in case an operation button has been just clicked on.
The ‘sign’ click handler switched the sign only if the afterOperation flag is set to false.

I really hope the article has been useful and adequately responding to your needs.

After the article about parsing xml/rss data with jquery’s ajax functions, I would now show you how the editing system for the Useful links repository page has been made.
What it actually does is editing/deleting and creating of rss files and respectively the items in them without a single refresh. The most relevant part of the client-side and the whole part of the server-side would be shown.

A demo of the system is here to be found
Please note that no data would be send to the server-side .php file – the ajax function doing this is commented and will not execute. That’s why when reloading the page you are going to see only the currently available categories and their corresponding items – changes made by you would not affect the files and its contents. Please also note that editing of a category or item, newly created by you would also be not possible, because of the same reason – editing is based on existing files and since the demo page actually does not create or alter anything in the categories folder on the server, it would not work as expected when for example trying to edit item in the category you have just added one to.

The files, used by the system:

– index.php – the admin start page, containing HTML and a bit of PHP to list all the currently existing category files (each category file is a RSS file, all available under the Useful Links Repository page)
– adminProcessesController.js – the client-side code which reads existing files and sends requests about file manipulation to the server-side page below (available from the link above)
– adminProcesses.php – the server-side code, which handles the ajax requests, done by the client-side page above
– RSSDocument.php – a file, containing the ifactnet_RSSDocument class, extending the DOMDocument PHP class.
– ifactnet_util.php – a file, containing some little functions (e.g. obtaining files in a folder by given extension, returning the absolute file name (without the extension) and so on…)
– style.css

The entry point – index.php – contains actually a few lines of code, whose main goal is to create the menu, used for the editing. The menu has the following structure:

Create new category

[Category 1]

Create new item

[Item 1 in Category 1]

[Item 2 in Category 1]

[Category 2]

Create new item

[Item 1 in Category 2]

…etc…

Clicking on each item or category link gives a possibility to edit it or delete it, creating of items and categories is also done by clicking on the corresponding “Create” option. Let’s now have a look at the more interesting files:

adminProcessesController.js

The current file is the most important, and so the biggest from the set above and would be unfortunately not possible to explain it in details, but I will try to cover the most important moments.
AJAX is used in two functions, declared at the very beginning of the file – the first one for reading an item or channel properties from a .xml file and the second one for sending requests to the php page:

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

// Find and return the selected item for edit

varloadSelected=function(indexSelected,path){

var$toEdit=null;

$.ajax({

type:"GET",

url:path,

cache:false,

async:false,

dataType:"xml",

success:function(xml){

if(indexSelected!=""){

var$items=$(xml).find('item');

$toEdit=$items.eq(indexSelected-1);

}else{

var$channelProperties=[];

$channelProperties.push($(xml).find("title").eq(0));

$channelProperties.push($(xml).find("description").eq(0));

$channelProperties.push($(xml).find("link").eq(0));

$toEdit=$channelProperties;

}

},

error:function(jqXHR,text,errorMsg){

alert("Error - "+errorMsg);

}

});

return$toEdit;

}

// Create, edit or delete item/category

varcallServerSide=function(properties,path){

varresponce="";

$.ajax({

type:"POST",

url:path,

cache:false,

data:properties,

dataType:"text",

async:false,

success:function(returnedData){

responce=returnedData;

},

error:function(jqXHR,text,errorMsg){

alert("The following error occured: - "+errorMsg);

}

});

returnresponce;

}

loadSelected variable (that is unnamed (anonymous) function, assigned to a variable):
The arguments are pretty much self-explanatory – indexSelected is the index of the selected item (obtained by clicking on its title – that a bit latter) and the second one is the path to the xml files. As already explained in a previous article about ajax – the path should be relative to the root directory of your server – for example, the paths, used in css and javascript files are relative to the .html file, where they are included. A path for ajax call to a file under ‘http://domainName.com/lib/news.rss’ should be “/lib/news.rss”, no matter where the javascript file, making the ajax call, actually is.
The ajax call parameters, used in the current function are to be found on the ajax methods documentation page in jquery’s website. There is, however, an important thing to notice – when returning any data, ‘fetched’ from the call, use async: false, like in the example above.
The success callback function returns the item node or an array of three of the channel’s node children – title, description and link. Its argument is the obtained xml (in this case – the whole xml file).

callServerSide variable (again unnamed (anonymous) function, assigned to a variable):
The function uses POST method to send the properties argument to the server side page, the path to which is assigned to path argument.data property of the ajax function should point to the data, which we are about to send. As you would see later – the data is a regular POST string with the form key1=”value1″&key2=”value2″. dataType is the type of data, expected as answer from the server-side script – in this case it is a plain text, as what the current server-side script returns is either “true” or “false”. The data, returned from the server is passed to the first argument of the success callback function – in our case that be returnedData. Of course, you can name the argument differently.

What the file does further:
It ‘splits’ the different links from the menu by purpose – item editing/deleting, item creating, or category editing/deleting and creating, assigning different anchor sets (depending on the anchors’ classes) to different variables (shown below).
Each set of anchors (for item editing/deleting or item creating, etc…) is handled a little differently on click. Basically, the handling procedures could be categorized as Creating and Editing/Deleting ones.
The creating procedures are a bit tricky, as the newly created item/category titles should be prepended to the menu on the go – as you remember, the menu is created in the index.php with a php code. However, as the aim is to accomplish all the tasks without reloading, the newly created items should be created in both the corresponding file (this is done by the php script) AND in the menu itself. Analogically – newly created categories demand creating of both the category file and the category ‘entry’ in the menu.
Editing procedures edit the content of the item/category in both the files and the menu entries.
When each of the procedures is started (by clicking on the corresponding menu entry(anchor)), a form is shown – with blank fields for creating procedure and populated ones for editing. Both are explained few lines below.
The form submission is the part, where the server-side script is called and the editing/deleting and creating processes are actually handled.

Let’s already come back to the code and especially the different kinds of menu entries:

1

2

3

4

5

6

7

8

9

...

var$navigation=$("#navigation");

var$navigationItems=$navigation.find("ul li a");

var$addCategory=$navigationItems.parent().children("a#addCategory");

var$addItem=$navigationItems.parent().children("a.addItem");

var$editCategory=$navigationItems.parent().find("a.category");

// An alternative way of traversing - parent().siblings() returns all the top-level <li> elements

What is omitted is the initialization of another variables, needed for the current implementation of the admin system. As the aim of the article is only pointing out the sole idea behind the ajax calls and the server side script, executed on their request, these are not included in the code. The dollar sign ($) at the beginning of each variable only denotes that the variable holds/points to jQuery object/set of objects.
The variables above are used as follows:

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

$($navigationItems).live('click',function(e){

e.preventDefault();

var$clicked=$(this);

$(".activeInMenu").removeClass("activeInMenu");

$clicked.addClass("activeInMenu");// colours the clicked item in red - only cosmetic

An important part here is the use of “live” – it binds the click event not only to the anchors, already created, but also to these, which are appended to the menu on the go – when an item or category is newly created.

What was omitted here (but shown a couple of rows below) is the call of the loadSelected() function. By item/category editing procedure, a form is created on the go and eventually appended to the main div in index.php. Its fields are populated with the data, returned from loadSelected() and a Delete button is added as well.
By creation process, the corresponding forms are shown with blank fields (these forms are already present in the index.php. They are, of course, hidden, until a creation link is clicked on).
Have a look at the code, handling item editing procedure, but have in mind that there are few functions and variables used, whose implementation and declaration are not shown. However, the functions are self-explanatory and all the variables represent different html elements. The only thing which could be of interest here, is the hideTheseNodeValues array – it contains all the item values, which are not to be edited – currently only the pudDate, actually.

...//notify on success or failure and edit the current category title in the menu

}

});

The serialize() function is the one, creating the POST string – as mentioned at the beginning of the article – it holds key-value pairs, where the keys are the form input names and values are the strings, typed in the corresponding input fields.
The creation processes are pretty much the same, as these shown above, except that they handle the additional appending of items to the menu – that is: [Item N in category M] menu entry for an item or
-[New category name]
– Create new item in [New category name]
menu entries for a whole new category.The issue: items are created in category files by the php script, categories are created as new files by the same php file, but all that results in different menu structure, which should be handled by the javascript, if no reloading is needed. The alternative of the on-the-go appending of menu entries is a simple refresh of the page – then index.php would list all the existing files and its contents. (I have written about that in the very beginning of the article). However, this refresh would make the whole ajax processing useless – each form action could call the adminProcesses.php file directly, which would handle the request accordingly and eventually reopen the index.php for further item/category processing from user’s side.

The last part of the file:

1

2

3

$deleteButton.live('click',function(){

...

});

handles the deleting of both item and category and removing its menu entries respectively. callServerSide function is called again, only with different parameters, of course.

adminProcesses.php

Finally, the complete server-side code:

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

<?php

require_once"RSSDocument.php";

require_once"ifactnet_util.php";

$categoriesPath=realpath("../categories/");

$allCategories=getAllFiles($categoriesPath,"xml");

if(isset($_POST['action'])&&isset($_POST['category'])){

$action=$_POST['action'];

$category=$_POST['category'];

$filePath=$categoriesPath."/".$category.".xml";

$updates=array();

$index="";

switch($action){

case"editItem":{

foreach($_POSTas$nodeName=>$nodeValue){

if($nodeName!="category"&&$nodeName!="index"){

$updates[$nodeName]=$nodeValue;

}elseif($nodeName=="index"){

$index=$nodeValue;

}

}

$rss=newifactnet_RSSDocument();

$rss->load($filePath);

$rss->updateItem($index,$updates);

$rss->save($filePath);

echo"true";

break;

}

case"createItem":{

$title=$_POST['title'];

$description=$_POST['description'];

$link=$_POST['link'];

$rss=newifactnet_RSSDocument();

$rss->load($filePath);

$rss->addItem($title,$description,$link);

$rss->save($filePath);

echo"true";

break;

}

case"editCategory":{

$title=$_POST['title'];

$description=$_POST['description'];

$link=$_POST['link'];

$rss=newifactnet_RSSDocument();

if(isset($_POST['newCategoryName'])){

$oldFilePath=$filePath;

$filePath=$categoriesPath."/".$_POST['newCategoryName'].".xml";

rename($oldFilePath,$filePath);

}

$rss->load($filePath);

$rss->title($title);

$rss->description($description);

$rss->link($link);

$rss->save($filePath);

echo"true";

break;

}

case"createCategory":{

$title=$_POST['title'];

$description=$_POST['description'];

$link=$_POST['link'];

$rss=newifactnet_RSSDocument();

$rss->channelProperties($title,$description,$link);

$rss->save($filePath);

echo"true";

break;

}

case"deleteItem":{

$rss=newifactnet_RSSDocument();

$rss->load($filePath);

$rss->deleteItem($_POST['index']);

$rss->save($filePath);

echo"true";

break;

}

case"deleteCategory":{

unlink($filePath);

echo"true";

break;

}

default:echo"false";

}

}else{

echo"false";

}

?>

The file uses couple of functions from the ifactnet_util.php, mentioned at the beginning of the article, which, I hope, are self-explanatory. The ifactnet_RSSDocument class is going to be included in another post for free use.

What adminProcessing.php actually does is to either edit, delete or create an item or a category, using a controlling variable – $action. As a response for each task, it simply echoes true on success, or false on failure, thus ‘sending’ it to the AJAX call (callServerSide()), which returns it to a certain variable (already in the javascript file – adminProcessesController.js). According to the answer, returned from the server side, either an error or success message message is shown.
The adminProcessing.php uses the POST request, sent from the AJAX call in its $_POST variable – take for example the following POST string – item=item1&title=title1, which would result in a $_POST array with two pairs key=>value – $_POST[‘item’] would give ‘item1’ and $_POST[‘title’] would give title1.

Conclusion

What AJAX enables us to do is to send either GET or POST requests to be (PUT and DELETE are available as well – refer to the ajax() manual in the jQuery website) processed by the server (in our case the server processing is actualy the adminProcesses.php file) without reloading the page.
Data sent to the server via POST method for example is available in the php $_POST array. The data is processed by the server and when needed is ‘returned’ to the same ajax call with a simple echo statement. When expecting data from the server-side, it is good to set the dataType property of the ajax function to the data type you are waiting – e.g. text, json or xml. However, not doing so would simply result in the so called “intelligent guess” – the jQuery would try to guess what type the received data is.
I hope that the article was of use for you, though its length and the fairly big amount of code not shown here, but taking part in the whole script.

In this tutorial I’ll show you how to achieve the split-flap display (aka airport departure board) effect with JavaScript. Now available also as Jquery plugin

Before we start with the coding, let my explain really quick what we’ll do. For the purpose of this tutorial I’ve prepared a table with strings. My if-act (effect) will be executed on mouse over and stopped on mouse out if necessary. Let’s get started!

When you look at an airport departure board what do you see? Yep, flipping characters! So lets begin by defining the chars we want to flip in a long string.

JavaScript

1

varchars="#@!$%&*()_-0123456789abcdefghijklmnpqrstuvwxyz ";

Let’s put this variable in the body of a constructor function that will be our flipper class.

JavaScript

1

2

3

functionflipper(obj){

varchars="#@!$%&*()_-0123456789abcdefghijklmnpqrstuvwxyz ";

}

As you can see the constructor has 1 parameter that is the object whose innerHTML we’ll flip. In order to do that we need the chars of the innerHTML in an array. Chopping a string to array is simple with the method .split() of the String class. I also use another two arrays. The first I called indexes holds the indexes of the chars that need to be flipped. The other one is the array that will be flipped and it holds indexes of chars in our chars variable. With a little bit of initialization we come to this:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

functionflipper(obj){

varchars="#@!$%&*()_-0123456789abcdefghijklmnpqrstuvwxyz ";

this.obj=obj;

this.textArray=this.obj.innerHTML.split("");

this.html=this.obj.innerHTML;

this.indexes=[];

this.cia=[];// CIA - just a coincidence. Stands for Character Indexes Array

this.interval;

var_this=this;

for(vari=0;i<this.textArray.length;i++){

this.cia.push(0);

this.indexes.push(i);

}

}

We’ll come to the rest of the variables in a moment but first take a look at the initialization loop. When the if-act starts every char from the innerHTML will start to flip from the char at position 0 in chars (#). I need all of them to start rolling and that’s why I push all indexes in the indexes array. Notice that indexes in this variable correspond to those of both the textArray and the cia. The flipping will be handled by a function called roll(). In its body there is a loop trough indexes. For every index I increment the value in cia and thus go another char forward from chars until I reach the char that is at the same index in textArray. In that case I exclude the index so that it’s not flipped anymore. The function looks like this:

Useful Links Repository was created with the intention to serve as a reference guide for valuable web development resources all over the web. The collected links are divided by categories, as each category is available as RSS Feed. There is for now no possibility for everyone to freely add resources, so please share your proposals and/or comments here.

The knowledge

I would be glad to share the knowledge gained from the creation process, posting it in the server- and client-side scripting categories and I hope the topics (DOM traversing with php and jQuery, ajax function calls with POST and GET types and the ifactnet_RSSDocment class, extending the DOMDocument) are all going to be useful as well. The creation of the admin system, offering instant modifications over the RSS files and their content with the help of AJAX requests, is briefly described here.