Facebook FBML Questions - javascript

I have a client looking to create a Facebook page very similar to http://www.facebook.com/enchantment
Inside the "Enchantment" page, you can see that there is a list of sub-tabs, "Enchantment, Blurbs, Excerpts, Order". I'm looking to create the same style, but I can't seem to figure out how. I've looked through the code and it appears they're using the "FBML Static" application for the main tab, and there's a ton of javascript to show and hide the tabs that I highly doubt was all written by hand.
Does anybody have any experience with this? Thanks in advance.

You will have to create a Facebook application via the My Applications link in the developers page. After you have filled in all the of the fields your app page should be up and running.
Now you need to begin developing the actual app on your website (you will have to specify the link in your application settings). Go through the Developer documentation, as they have quite a good documentation.
So, in order to actually create those tabs, its actually very simple, all you have to do is utilize FBMls clicktoshow and clicktohide attributes. Essentially all you need is the following code:
Link 1
Link 2
Link 3
<div id="nav1">
//content for first tab
</div>
<div id="nav2">
//content for second tab
</div>
<div id="nav3">
//content for third tab
</div>
When Facebook 'imports' this (only via FMBL, I'm unsure if this works with iframe) it conveniently does all the work and converts the above links to something like:
<a href="#" clicktoshow="nav1" clicktohide="nav2, nav3" class="test"
onclick="(new Image()).src = '/ajax/ct.php?app_id=7146470109&action_type=3&post_form_id=fd583a515fe76b1d3d300e974aba931d&position=16&' + Math.random();FBML.clickToHide("app7146470109_nav2");
FBML.clickToHide("app7146470109_nav3");
FBML.clickToHide("app7146470109_nav4");FBML.clickToHide("app7146470109_nav5");FBML.clickToHide("app7146470109_nav6");
FBML.clickToHide("app7146470109_nav7");FBML.clickToHide("app7146470109_nav8");FBML.clickToShow("app7146470109_nav1");return false;">Test</a>
But, you only have to worry about the first part, as Facebook takes care of the second. As you can see it is a fairly straightforward process.

They're probably just capturing the click event, and simply showing and hiding different divs based on that. You can create a static FBML tab, and do something like this inside of it:
<ul>
<li><a id="afoo" href="#foo" onclick="gotoFoo(this); return false;">Foo</a></li>
<li><a id="abar" href="#bar" onclick="gotoBar(this); return false;">Bar</a></li>
</ul>
<div id="foo">
This is content of the foo tab
</div>
<div id="bar" style="display:none;">
This is content of the bar tab
</div>
<script>
var foo = document.getElementById('foo');
var bar = document.getElementById('bar');
var afoo = document.getElementById('afoo');
var abar = document.getElementById('abar');
var gotoFoo = function(target) {
abar.removeClassName('selected');
bar.setStyle({display: 'none'});
afoo.addClassName('selected');
foo.setStyle({display: 'block'});
};
var gotoBar= function (target) {
afoo.removeClassName('selected');
foo.setStyle({display: 'none'});
abar.addClassName('selected');
bar.setStyle({display: 'block'});
};
</script>
I haven't created any styles for you, but what the code above does is it hides and shows the "foo" and "bar" divs depending on what you click on. It also adds the class name "selected" to the anchor tag that was clicked on so that you can set some styles to give a visual cue as to which tab is currently active. You'll definitely want to add some styles to pretty this up.
I hope this helps.

You cannot see directly the code since the code written in FBML gets parsed by Facebook before it's delivered to the browser and transformed into HTML; that's why you see a lot of JavaScript.
Actually it doesn't look so complex so I believe it was actually written by hand with JavaScript.

Related

How can I "stream" a section of my webpage to another window?

I want to stream a certain container on my webpage to another window.
The setup is similar to a Point of Sale system. ie an operator-facing display and a second customer-facing display.
The operator-facing display will have a window with all the toolbars, menus etc. While the customer-facing display will only show a certain container from the first operator-facing window.
As below: The Operator Display will contain the full webpage content. While the customer display will only contain the #output container.
Operator Display
<div id="toolbar">
<ul>
<li><button>Action 1</button></li>
<li><button>Action 2</button></li>
</ul>
</div>
<div id="output">
//OUTPUT GOES HERE
</div>
Customer Display
<div id="output">
//OUTPUT GOES HERE
</div>
Is there anyway to do this?
Since you put "stream" in quotes, I assumed that you are looking for different solutions for this problem.
In browsers you can easily open a new window and control it from main page, I've created a small snippet which implements a case, where on one window you can add items and display them on another one.
These lines are most important:
const posWindow = window.open("about:blank", "customerDisplayWindow", "height: 50,width: 50");
posWindow.document.body.innerHTML = '<h2>Items</h2><ul id="item-display"></ul>';
You could come up with much cleaner solution than modifying document but you get the idea.
https://jsfiddle.net/jhd5L8wa/1/
I suggest reading MDN page about Window.open() (especially third argument, windowFeatures) to learn more about how opened window will look and behave.

addThis button not clickable via jQuery

I've tried looking at the documentation for addThis and it seems like it's being updated or something because all the links these help posts link to don't even mention the API bits they describe.
Anyway,
I just need to be able to programmatically click an addThis button. However, I can't seem to do it via console before I implement it in my code.
I read that this has something to do with how the addThis listeners are added only when the document is done loading. This doesn't make sense to me because even if I manually try to trigger a click in console, it still does nothing but return the html of the link I'm trying to trigger. For example:
`$('.at-svc-facebook').click();`
OR `$('.at-svc-facebook').trigger('click');`
OR `$('.at-share-btn.at-svc-facebook').click();`
I mean, by the time I open console the dom is ready. So then what else might be preventing me from clicking these buttons via jQuery?
I've tried adding a listener to an element myself, and then clicking it programmatically, and it works. So something is different about the way addThis listens for a click. I may update this question with something I find after inspecting their js.
===================
This is what is in the DOM which addThis populates and listens to:
<div class="addthis_sharing_toolbox"></div>
This is what ^ that code is turned in to from addThis:
<div class="addthis_sharing_toolbox" data-url="http://localhost:8001/halloween/" data-title="33 Halloween Costume Ideas">
<div id="atstbx" class="at-share-tbx-element addthis_32x32_style addthis-smartlayers addthis-animated at4-show">
<a class="at-share-btn at-svc-facebook">
<span class="at4-icon aticon-facebook" title="Facebook"></span>
</a>
<a class="at-share-btn at-svc-twitter">
<span class="at4-icon aticon-twitter" title="Twitter"></span>
</a>
<a class="at-share-btn at-svc-google_plusone_share">
<span class="at4-icon aticon-google_plusone_share" title="Google+"></span>
</a>
</div>
</div>
Now, you can see the jQuery I'm using to click the buttons and the code it's trying to click.
The issue is that addThis was putting a second link with the exact same class in the DOM for some reason. It generates some HTML and appends it to body.
So what I needed to do to select the button and trigger a click was to specify the 2nd element in the array of elements and call click on that one. Like so:
$('.at-svc-facebook')[1].click();
Now, the next problem I face is chrome block a programatic popup, but that's beyond the scope of this question. :(
change the
var class_name = $(this)[0].className;
as below,
var class_name = $(this)[0].attr('class');
and it'll work. :)

Zeroclipboard, triggered by any element with class="copy"

I've looked through this site along with many others and I can't see the answer anywhere.
I currently have a site with multiple buttons and a preview pane. The text shown in the preview pane differs depending on the button that the user is currently hovering over.
<body>
<div="preview_pane"> <!--ALL TEXT IS SHOWN HERE --> </div>
<div id="button_group">
<div class="copy_me" id="stock1"></div> <!--THIS SHOWS STOCK TEXT-->
<div class="copy_me" id="stock2"></div> <!--COMPLETELY DIFFERENT TEXT-->
<div class="copy_me" id="stock3"></div> <!--YET SOME OTHER DIFFERENT TEXT-->
<div class="copy_me" id="stock4"></div> <!--OTHER COMPLETELY DIFFERENT TEXT-->
</div>
</body>
What I want to do is have zeroclipboard create the flash overlay on any button with the class copy_me. All of these buttons need to copy the text shown in the preview pane.
This way when the user hovers over the button the text in the preview pane will change and then when they click, the text in the preview pane will be copied to the users clipboard.
I can't manually add the script to every button as there will be over 50 stock text buttons.
I have no experience in flash or javascript (only dabbled in jQuery) so this is something completely new for me.
Any help will be greatly appreciated.
answered a similar question at https://stackoverflow.com/a/26200988/3471658
Try using http://www.steamdev.com/zclip/ it allows you direct access to jquery and you can use your own logic in the return statement.
include jquery.zclip.js
download and save ZeroClipboard.swf
Here is a snippet:
$(".class-to-copy").zclip({
path: "assets/js/ZeroClipboard.swf",
copy: function(){
return $(this).attr("data-attribute-with-text-to-copy");
}
});
Make sure you change the path of the swf.
I looked at the api docs for zeroclipboard right quick, and I you want to use the glue method, and pass an array of dom nodes. In this case, you want all the nodes with the class name "copy_me", so:
var clip = new ZeroClipboard();
clip.glue(document.getElementsByClassName('copy_me'));
You mentioned jQuery. This should make things easier for you:
var client = new ZeroClipboard($('.copy_me'));
See:
https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/instructions.md
Also see:
http://jsfiddle.net/rimian/45Nnv/

changing dynamically the "onlink" id in css

I made a navigation bar as tabs in my website, and I used the onlink identity to specify the current tab with certain characteristics. My problem is that when I change tabs, I don't know how to make the previous tab id set as none and the current one set as onlink.
Here's the navigation bar code:
<div id="indNavBar">
<div id="indHolder">
<ul>
<li><a onclick="DisplayDIV('IndPage');HideDIV('DoubleInd')" id="onlink">Single Indicator</a></li>
<li><a onclick="DisplayDIV('DoubleInd');HideDIV('IndPage');">Double Indicators</a></li>
</ul>
</div>
</div>
There's a simple ways but it's somehow stupid, which is to make each current tab as a whole page and when I click another tab, it's just given the url of clicked tab which goes to the page with specified onlink id, but this requires reloading the whole page that's why I'm seeking a better solution.
You can get the control being clicked by passing this in javascript method
onclick="DisplayDIV('IndPage', this);
function DisplayDIV(IndPage, sourceObj)
{
alert(sourceObj.id);
}
Are you ok do use the jQuery Library?
If so you can avoid putting inline javascript into your html and use toggleClass http://api.jquery.com/toggleClass/
You are trying to use HTML ids in the wrong way.
Ids are unique identifiers for HTML tags. They should not change at runtime.
Instead, apply CSS classes to the tab you want to be visible.
CSS
.hide {display:none;}
Javascript
var indpage = document.getElementById("IndPage");
if (!indpage.classList.contains("hide")) {
indpage.classList.add("hide");
}
Then your HTML at runtime will change to
<div id="IndPage" class="hide">...</div>
This is the standard approach.
And you can do much more with this idea.
I agree that making a tab a whole page is not a good idea. You can use javascript to apply CSS classes to hide and remove that class to show again.
Its also a good idea to learn how to separate your javascript from your HTML. Please read some more tutorials on this. One for instance: Unobtrusive Javascript
Here is a jquery way to do it: http://jsfiddle.net/surendraVsingh/HyAhL/
$('#indHolder a').click(function(){
$(this).attr('id', 'onlink');
$(this).parent().siblings().find('a').removeAttr('id');
});​
I took hints from the answers above and it worked as the following:
function putOnlink(x){
document.getElementById('onlink').id = "none";
$(x).attr('id','onlink');
}
and the tabs code is:
<div id="indNavBar">
<div id="indHolder">
<ul>
<li><a onclick="DisplayDIV('IndPage');HideDIV('DoubleInd');putOnlink(this);" id="onlink">Single Indicator</a></li>
<li><a onclick="DisplayDIV('DoubleInd');HideDIV('IndPage');putOnlink(this);document.getElementById('onlink').id='none'">Double Indicators</a></li>
</ul>
</div>
</div>
I just wanna not that in the second link I had to change the id of the first link twice because it didn't work once, maybe cause its id is set in the tag not just when clicked.

Selecting a tab with jQuery tools

I set up the jQuery Tab tools on my web application, and it's working fine to click between the tabs, but what I would like to do is be able to select a tab after another javascript function completes. I'm having trouble doing this successfully after reading through the documentation and searching.
I have a search function, and when someone searches, I'd like the search tab to be selected and come into view.
At the end of the search function:
var tabby = jQuery('#right-tabs').tabs();
tabby.tabs('select', 1); // switch to second
The HTML:
<div id="right1">
<ul class="tabs" id="right-tabs">
<li>Articles</li>
<li>Search results</li>
</ul>
<div class="panes" id="right-panes">
<div id="articles-panel"></div>
<div id="search-results-panel"></div>
</div>
</div>
I got a firebug error saying "Uncaught TypeError: Cannot read property 'jquery' of undefined".
I also tried another approach... just manually setting/removing the classes, with this:
jQuery("ul#right-tabs a").removeClass('current');
jQuery("ul#right-tabs a#search-tab").addClass('current');
jQuery("div#articles-panel").hide();
jQuery("div#search-results-panel").show();
That works, but it creates a strange behavior, of not letting you click on any other tabs until you click on the selected tab, and then it will let you click the other ones.
So, I'm not exactly sure how to make jQuery tools cooperate with what I want to do. It should be simple, I'm considering bailing on this and just writing it from scratch. But if you guys have a way to make either approach work, or a better way, I would really appreciate it!
UPDATE
All I needed was:
var api = jQuery("ul#right-tabs").data("tabs");
api.click(1);
I was mistakenly finding examples for the jQuery tabs and not the jQuery tools tabs.
What I needed was:
var api = jQuery("ul#right-tabs").data("tabs");
api.click(1);
I was mistakenly finding examples for the jQuery tabs and not the jQuery tools tabs.

Categories