[Pro] How to create Google-like moveable sections

Hey, Guys –

You know how if you have iGoogle set up to deliver RSS Feeds to your Google home page, it allows you to move certain boxes around? In other words, you can take the RSS box for The New York Times and grab it and move it around on the page and place it where you want?

Is there a way to do that in Freeway?

Thanks,
Jamie


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Example here http://www.deltadesign.co/odds/draggable.html

Walter’s work of course!

David


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Here’s another trick, more like what Google does.

New page, CSS Positioning on.

Draw a large HTML box on the page. Freeway will name it item1.

Double-click inside that box so you get a text cursor, and use
Insert / HTML Item to insert an inline HTML box.

Drag it out to a larger size, set it to have a background color, Float
left, Padding right and bottom if you like, and then use the Item /
Extended / Div Style dialog to add the style pair cursor:move. (This
last part is strictly optional.)

Click once on the inline box to select it (handles showing) and copy
to the clipboard.

Double-click in the parent box and press the down-arrow a bunch of
times so your cursor is after the first inline box. Now paste a bunch
of times.

Double-click inside each of these inline boxes and add a letter or a
number so you can tell them apart.

Now apply Protaculous to the page, choose scriptaculous-packed from
the Library picker, and click the top Function Body button. Paste in
this line of code:

Sortable.create('item1',{tag:'div',constraint:false});

Preview. Notice how you can drag and drop the elements into a new
order. Reload the page, and the pieces go back where they started.

You can cause this order to persist using a server-side application,
and that is precisely what Google are doing on their page. They
recognize you from your login and cookie, and when they show you
“your” page, it’s drawn that way for only you, using the data they
have stored about you. This is the same mechanism I use here: http://cms.walterdavisstudio.com/admin.php
to maintain the navigation tree. You drag and drop the pages and
folders around, and if you reload the page, you’ll see that the server
has stored the order.

Walter

On Mar 26, 2011, at 5:54 AM, DeltaDave wrote:

Example here http://www.deltadesign.co/odds/draggable.html

Walter’s work of course!

David


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Cool stuff, as always, Walter and Dave. This might come in handy on a future project.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thanks, guys! I appreciate all the input.

Best,
Jamie


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On 26 Mar 2011, 2:52 pm, waltd wrote:

You can cause this order to persist using a server-side application,
…This is the same mechanism I use here: http://cms.walterdavisstudio.com/admin.php
to maintain the navigation tree. You drag and drop the pages and
folders around, and if you reload the page, you’ll see that the server
has stored the order.

Hi Walter

How could one build that behaviour in? How do you set those cookies?
I am working on a CMS project where members log in on a page with lot of information. If I make the DIV’s draggable, and if they would stay that way, each member could organise the content on his own page in their own way.

much obliged.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On your CMS back-end, you will need to have a place to store these preferences. If your user account is in the users table, for example, you could add a string column to that table and store the order of the elements in a comma-delimited array notation. Then when you build that page for the user, you would read that back out and use it to order the widgets on the screen as you build their custom view of the page.

So for example, you have user 42, and their record looks like this:

$user->widgets = 'weather,sports,news'

and user 43 looks like this:

$user->widgets = 'news,sports,weather'

To read that back out, you would take the value of the widgets column, split it by comma, and use that to set the order while you are building the page on the server:

foreach(explode(','.$user->widgets) as $widget){
	$user->render_widget($widget);
}

Then, to re-set the order, you would need to provide a sortable layout (I don’t recommend having this be the default layout, only when the user has switched into a mode that means she really wants to sort.) Within that layout, you can either set Sortable to work each time the order changes, or call it manually at the end of the sorting operation.

If you’ve given your sortable elements the proper IDs (widget_news, widget_sports, and widget_weather), then Sortable.serialize will generate an array notation like this: sort_me=weather&sort_me=sports&sort_me=news, which your server will take in as an array called sort_me.

If you look at the source of this page: http://scripty.walterdavisstudio.com/sortable/ you’ll see how to set this up, and the ‘save_sort_order.php’ page that it’s calling out to is just this line of code:

print $_POST['id'] . ': ' . implode(',', $_POST['sort_me']);

(It doesn’t actually save anything in this example, in other words.) If you wanted to save the current order, you would just use the result of implode(',', $_POST['sort_me']) as the value to set in your widgets column, and then use it as I sketched out earlier.

Walter

On Nov 4, 2011, at 4:31 PM, atelier wrote:

On 26 Mar 2011, 2:52 pm, waltd wrote:

You can cause this order to persist using a server-side application,
…This is the same mechanism I use here: http://cms.walterdavisstudio.com/admin.php
to maintain the navigation tree. You drag and drop the pages and
folders around, and if you reload the page, you’ll see that the server
has stored the order.

Hi Walter

How could one build that behaviour in? How do you set those cookies?
I am working on a CMS project where members log in on a page with lot of information. If I make the DIV’s draggable, and if they would stay that way, each member could organise the content on his own page in their own way.

much obliged.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thanks, Walther.

If I understand this well, I need information from the page (actual sorting of ‘widgets’) to be send to the server and stored in an extra table as comma separated values for later use.
The php script writes back the order when the user visits the page again.

ExpressionEngine is able to output userdata (like user_id) to the browser (frontend). And I can also make a page output PHP, I guess for sending data back to the database.

Unfortunately I lack knowledge of PHP and serverside scripts. Pity. Way beyond my leage, this is…


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On Nov 4, 2011, at 7:36 PM, atelier wrote:

Thanks, Walther.

If I understand this well, I need information from the page (actual sorting of ‘widgets’) to be send to the server and stored in an extra table as comma separated values for later use.
The php script writes back the order when the user visits the page again.

ExpressionEngine is able to output userdata (like user_id) to the browser (frontend). And I can also make a page output PHP, I guess for sending data back to the database.

Unfortunately I lack knowledge of PHP and serverside scripts. Pity. Way beyond my leage, this is…

If you’re using EE, then you’re already using PHP. It’s not that great a leap if you need to add this. If you can get EE to process a form, then that’s about all there is to saving the order. The only slightly tricky part will be to get your template blocks to play back in the correct order. The name for this is “metaprogramming”, where you cause the program (the script that draws the home page) to re-write itself on the fly.

If you can get the page to draw in a particular order to begin with, possibly through organizing some blocks of code in your template, then you can take it the next step and get the template to respond to the user’s choice.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thanks for the answer, Walter. As always. You have helped me more than once.

I think I could provide some parts in your PHP script with data from an extra table for userdata, I could be close. But I do not have the time right now. It’s not that I give up easy, but I must be effective, and I know how timeconsuming this can be, bearing in mind that I have no programming skills.
I let this one go for the moment, maybe I dive into it later… I promise that if I manage, I’ll be back here to share.

Thanks

Hans


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

I had the same question on two different mailing lists within the same day (this one and the Prototype/Scriptaculous list) so I made an example last night, working from the page I posted here yesterday. (If you look at the example again, you’ll see that its persisting your changes through reloads, because it’s now backed by the database.) Here’s what I posted:

table: widgets
id int(11) primary key, auto-incrementing
name varchar(255)
position int(11)

index.php: simplepastiefile.php · GitHub

save_sort_order.php: simplepastiefile.php · GitHub

http://scripty.walterdavisstudio.com/sortable/

Walter

On Nov 5, 2011, at 5:32 AM, atelier wrote:

Thanks for the answer, Walter. As always. You have helped me more than once.

I think I could provide some parts in your PHP script with data from an extra table for userdata, I could be close. But I do not have the time right now. It’s not that I give up easy, but I must be effective, and I know how timeconsuming this can be, bearing in mind that I have no programming skills.
I let this one go for the moment, maybe I dive into it later… I promise that if I manage, I’ll be back here to share.

Thanks

Hans


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Fantastic, I give it a try.

Just for my understanding, this in index.php

‘mysql://test:pass@localhost/test’);

means:

database: test

server: localhost

username: pass

password: …?

and are you talking here about two tables?

table: widgets id int(11) primary key, auto-incrementing name varchar(255) position int(11)

table 1: widgets id int(11) primary key

table 2: auto-incrementing name varchar(255) position int(11)

My apology for my lack of knowledge.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

I am asking this because I can add fields connected to logged_in members, the data in the field will be stored in the member-table in the MYSQL database. I can name them as I want, I can also see which id these fields have. I can make the content of these fields appear in the HTML, aka PHP page on the server.

I could also add tabels, but I am not sure what to do with them next.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

On Nov 6, 2011, at 8:30 AM, atelier wrote:

Fantastic, I give it a try.

Just for my understanding, this in index.php

‘mysql://test:pass@localhost/test’);

Think of it like this:

mysql://username:password@servername/database

This format is called a DSN, and it’s a kind of URL for database connections.

means:

database: test

server: localhost

username: pass

password: …?

and are you talking here about two tables?

table: widgets id int(11) primary key, auto-incrementing name varchar(255) position int(11)

table 1: widgets id int(11) primary key

table 2: auto-incrementing name varchar(255) position int(11)

My apology for my lack of knowledge.

That’s just one table, called widgets, and the indented lines below the first one are the column names and types. (I just looked, and the indenting didn’t show up on the Web view. Here’s what you should have seen:

table: widgets
	id int(11) primary key, auto-incrementing 
	name varchar(255) 
	position int(11)

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

If you want to store multiple versions of the layout, on a person-by-person basis, you’ll need to store the entire layout order as a variable on the members table, probably using the comma-delimited format I mentioned earlier.

You can use the index.php code as an example of how you would use the order of the elements to drive assembling the page, but that example is backed differently in the database than what you need, so while you can look at that example as a “simplest thing that could possibly work”, it’s not going to meet your needs, since it is designed to persist a single order for all visitors to the page.

So you need to get in between the member signing in and the member seeing “her” home page. In that interstice, you will want to change the home page template so that it draws the widgets in the order that your member has decided is most pleasing. Without seeing the code that creates your home page, I’m not able to give you a code example that would be relevant, but I can do a bit of pseudo-code here that hopefully will explain what you need to do.

Sticking to my newspaper terminology, let’s say your home page template has some function to draw a widget on the screen, and that function gets called a bunch of times, with a different variable value being passed each time:

<?= draw_widget('news', $member) ?>
(bunch of other layout here)
<?= draw_widget('sports', $member) ?>

Your next step is to store the layout order, probably (as I described earlier) in a comma-separated list in the member table. Read that back out, so you get an array of template names, and call it $layouts. Now your home page template can look like this:

<?= draw_widget(array_shift($layouts), $member) ?>
(bunch of other layout here)
<?= draw_widget(array_shift($layouts), $member) ?>

And the order of the widgets will be dynamic, saved by the user’s preference. If you imagine a deck of cards as your array, array shift “deals” a card off the top of the deck and gives you the value. In the process, the card is removed from the deck, so the next time you call array_shift, you get the next card.

Now assuming again that all of your layout is sufficiently flexible that it doesn’t matter what goes where, the user can sort the layout and each user can see a custom arrangement of the same content.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thank you.
As I understand you, i must create a table called: widgets, whith has three fields, named

Id int

Name varchar

Position int


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

If you want to experiment with my example as posted, yes, that’s absolutely correct. This will get you the ability to store the current position of those widgets as I showed them, and change their order by drag-sorting them. And just by adding more widgets to the database table, you can have as many boxes on the page, three across, as you like.

My example code only allows you to save one order to the widgets: whatever order the last person to drag them left them in.

For what you were initially looking at doing, though, you will need something else.

First, you will need to store each member’s preferred order somewhere. This means adding an additional column in your members table.

Second, you will need a sortable layout where the members can set their own preferred order, and this will need to be hooked up to the save_sort_order.php script, so that the ID of the member is passed along with the order of the widgets, and thereby the correct member’s row in the database is updated with the new order.

Third, you will need to re-jig your existing page layout system so that the order of the widgets isn’t hard-coded, but dynamic.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

I can call memberdata as soon as a member has been logged in. EE can spit out member-related data in any Template (home page)
Would your scripts also work when I add the fields in my member table, and call them from there? In that case I must rename in the script ‘widgets’ into ‘member_data’ Possible?


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Each row in your member_data table would need to have a field where you store the order for each member. The script that I wrote uses a different methodology, so you would need to write a different script that handled things on a user-by-user basis, rather than a single table holding the order for the individual widgets. You can think of the system I wrote as being a very lightweight CMS in and of itself, storing the content for a series of blocks and incidentally storing their order of appearance.

I still haven’t seen anything from you that describes this content you’re allowing the user to sort, and where it comes from. That’s a critical step in this whole thing.

Let’s think about this a different way: you have members like this:

member_data:
    id
    name
    address
    email
    front_page_order

and home page content like this:

contents:
    id
    title
    teaser
    body
    metadata
    added_at

So your basic (unsorted) home page script could look like this:

$template = '<div>
    <h2>%s</h2>
    <p>%s</p>
    <p>
        <a href="page.php?id=%s">
            Read more
        </a>...
    </p>
</div>
';
$contents = MyActiveRecord::FindAll('contents', null, 'added_at DESC');
foreach($contents as $content){
    printf($template, $content->title, $content->teaser, $content->id);
}

And that gets you a list of the contents in latest-first order and shows teasers to them on the page.

Now if you have a layout set somewhere that allows each user to save a sort order in their own member_data row, you would modify your content playback function to use that order. Working from the example above, I would store the id of each content element, so if a particular user wanted to see 3,5,4,2,1 order, I would save that as a comma-separated list in their member_data row. MyActiveRecord has a neat shortcut to getting the records back in that case – all you have to do is pass it an array of ids and it returns an array of records:

$member_order = explode(',', $member->front_page_order);
//now that's an array of ids
$contents = MyActiveRecord::FindById('contents', $member_order);

The rest of the code would be the same, because the only difference now is the order of the elements. You iterate over the collection the same way, and the output is the same.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

I am away here for some days, I’ll post the page code asap.
I try to perform some tests as well. …I’ll be back… :slight_smile:


freewaytalk mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options