I'm curious to know whether Meteor would be suitable for following, and how I would go about writing the code.
I'd like to create a webpage, where by the code in a specific "div" can be hotswapped on the fly to users currently looking at that page. (eg. the div contains some text, but then an image replaces it.) Ideally, the swap would be executed manually by the the webpage's admin through the click of a button, or some code fired off on the server or something. Regular viewers to the webpage would not be able to do this - they only see the live changes on the page.
real-life example:
live internet broadcast is off-air, therefore the "div" contains "off-air" text. live hotswap of code happens when broadcast goes on-air, and the viewers of the webpage now see the html5 broadcast player in the "div" instead. later it is swapped back once the broadcast goes off-air.
I'm completely new to the Meteor platform, so I consider myself a newbie :) Any help is appreciated.
You might better off by using a reactive div using data from a collection (I'm going to use an example with raw HTML but you might be better off implementing your own functionality with what content to display instead: i.e
Basically take advantage of reactivity over hot code swaps
Client side html code
<template name="home">
<div>
{{{content}}}
</div>
</template>
js code
if(Meteor.isClient) {
MyCollection = new Meteor.Collection("MyCollection")
Template.home.content = function() {
if(MyCollection.findOne()) {
return MyCollection.findOne().content
}
}
}
if(Meteor.isServer) {
MyCollection = new Meteor.Collection("MyCollection")
//Set an initial content if there is nothing in the database
Meteor.startup(function() {
if(!MyCollection.findOne()) {
MyCollection.insert({content:"<h1>Test content</h1><p>Test Data</p>"
}
}
//A method to update the content when you want to
Meteor.methods({
'updatecontent':function(newcontent) {
id = MyCollection.findOne()._id
MyCollection.update(id, {$set:{content:newcontent}});
return "Done"
}
}
You can update your content either in the mongo collection or with something like (in your web console, client side or server side javascript):
Meteor.call("updatecontent","New content",function(err,result) {
if(!err) {
console.log(result)
}
});
Which will update the code live when you use it.
I'm sorry it's quite long but the bulk of it is setting/updating the html. Its actually much nicer than a hot code swap which would refresh the user's page
Related
I am following this example https://kadira.io/academy/meteor-routing-guide/content/rendering-blaze-templates
When I click on my links the whole page is being reloaded. Is there any way to load only the template part that is needed and not the whole page?
Edit: Also I noted another problem. Everything that is outside {{> Template.dynamic}} is being rendered twice.
Here is my project sample. https://github.com/hayk94/UbMvp/tree/routing
EDIT: Putting the contents in the mainLayout template and starting the rendering from there fixed the double render problems. However the reload problems happen because of this code
Template.mainLayout.events({
"click *": function(event, template){
event.stopPropagation();
console.log('body all click log');
// console.log(c0nnIp);
var clickedOne = $(event.target).html().toString();
console.log('This click ' + clickedOne);
//getting the connID
var clientIp = null // headers.getClientIP(); // no need for this anymore
var clientConnId = Meteor.connection._lastSessionId;
console.log(clientIp);
console.log(clientConnId);
Meteor.call("updateDB", {clientIp,clientConnId,clickedOne}, function(error, result){
if(error){
console.log("error", error);
}
if(result){
}
});
}, // click *
});//events
Without this event attached to the template the routing works without any reloads, however as soon as I attach it the problem persists.
Do you have any ideas why this code causes such problems?
EDIT 2 following question Rev 3:
event.stopPropagation() on "click *" event probably prevents the router from intercepting the click on link.
Then your browser performs the default behaviour, i.e. navigates to that link, reloading the whole page.
EDIT following question Rev 2:
Not sure you can directly use your body as BlazeLayout target layout.
Notice in the first code sample of BlazeLayout Usage that they use an actual template as layout (<template name="layout1">), targeted in JS as BlazeLayout.render('layout1', {});.
In the tutorial you mention, they similarly use <template name="mainLayout">.
That layout template is then appended to your page's body and filled accordingly. You can also change the placeholder for that layout with BlazeLayout.setRoot() by the way.
But strange things may happen if you try to directly target the body? In particular, that may explain why you have content rendered twice.
Original answer:
If your page is actually reloaded, then your router might not be configured properly, as your link is not being intercepted and your browser makes you actually navigate to that page. In that case, we would need to see your actual code if you need further help.
In case your page does not actually reload, but only your whole content is changed (whereas you wanted to change just a part of it), then you should make sure you properly point your dynamic templates.
You can refer to kadira:blaze-layout package doc to see how you set up different dynamic template targets in your layout, and how you can change each of them separately (or several of them simultaneously).
You should have something similar in case you use kadira:react-layout package.
I have an FileUpload control on a page. I need to change some values based on the filename once a user selects a file. I'm trying to find out the best way to do this. The only option I can see is listening in JavaScript for a change event and then either..
a) forcing a post back and updating the form
b) updating things on the client side using JavaScript and some back end async calls.
Is there any other options and if not which of this is preferable?
Thanks
If you are using jquery, you can attach a function to the change of the file upload.
Consider the following example html:
<input id="myFile" type="file">
<p><label id="myLabel">No File</label></p>
And let's say we wanted to update the label with the name of the selected file. To do that, we'd use the following javascript:
$(document).ready(function () {
$("#myFile").change(function () {
$("#myLabel").html($(this).val());
});
});
Here's a fiddle in action: http://jsfiddle.net/ffkuL/1/
If you aren't using jquery, you can do something like this:
var upload = document.getElementById("myFile");
upload.onchange = function (e) {
var label = document.getElementById("myLabel");
label.innerHTML = this.value;
};
And here's a fiddle for that one: http://jsfiddle.net/8PYwK/
(Honestly, though, I find that it's far simpler in the long run to use jquery in the long run when dealing with ASP.NET controls.)
Obviously, the label changing in my samples are just examples. Following that pattern, though, you can make whatever changes you need to on the client side (rather than needing to post back).
The jQuery UI dialog drives me up the walls. To the best of my understanding, here's how it works:
When you do $('#myDialog').dialog({...}), it copies the #myDialog element and moves it inside this bizarre widget thing at the bottom of your body tag. This is crazy! It will duplicate possibly unique DOM elements (with ids) when it does this.
So what I'm trying to do is make it behave in a predictable way when I refresh the HTML of the original element (#myDialog). If I do this dynamically, sometimes the dialog doesn't open any more:
http://jsfiddle.net/t67y7/3/
Or sometimes the dialog opens with the old HTML (because it's cached at the bottom of the page that way). What is up with this?
Since nobody seems to have any idea how to tame this beastly dialog, here's the best thing I've come up with to date. I'll accept any superior alternatives.
var original = $('#dialogId')[0];
var clone = $(original).clone().attr('id', 'dialogIdClone');
var saveHtml = $(original).html();
$(original).html('');
$(clone).dialog({
... // other options
open: function (){
// add any dynamic behavior you need to the dialog here
},
close: function(){
$(clone).remove();
$(original).html(saveHtml);
}
});
The purpose of this whole craziness is to keep the HTML of the original dialog unique on the page. I'm not really sure why this can't be the built-in behavior of the dialog... Actually, I don't understand why jQuery UI needs to clone the HTML to begin with.
I know this has been posted for a while, but a less extensive way to handle this issue would be:
$('#your-dialog').dialog({
... // other options
open: function (){
// add any dynamic behavior you need to the dialog here
},
close: function(){
}
});
$('#your-dialog').remove();
This is due to dialog widget wants to be able to control the display and will wrap the inner content of the original dialog then create a brand new one at the bottom of the body.
The draw back of this solution is that the dialogs have to be the first to be initialized to ensure all your 3rd party library widget will operate properly.
Why don't you just call $("#dialogId").dialog("destroy") on close function, like this:
$("#dialogId").dialog({
close: function() {
$(this).dialog("destroy");
// you may want empty content after close if you use AJAX request to get content for dialog
$(this).html('');
}
}
The destroy function will remove the decorated code, and your dialog element will not be duplicate next time you show the dialog.
I added a sample code to jsfiddle.net example.
You need to empty the dialog before opening it.
$("#dialogId").html('');
$("#dialogId").dialog({
close: function() {
$(this).dialog("destroy");
}
}
I was looking for any way to create web page,so that user wont be able to copy content from my web page. i.e. User wont be able to select the any text present on the webpage.
Let's assume i am working on asp.net
Any interesting ideas to accomplish the task ?
Ultimately you can't.
If you disable the ability to select text, the context menu or even just the copy option from the context menu users will still be able to see your content.
If they can see it they can copy it:
Take a screenshot.
Take a photo.
Type the text they see into Notepad.
Dictate the text into a recorder.
It's not worth the development effort and you won't stop the determined copier. All you'll end up doing is annoying your legitimate users.
Add value to your site so people want to keep coming back rather than just taking content and running. This could be:
Allow user generated content to expand on what's there.
Update content regularly so it's always fresh.
You can use user-select CSS3 propertie
HTML like this :
<span class="protected">Datas you wants protect</span>
And the correspondant CSS :
.protected {
-moz-user-select:none;
-webkit-user-select:none;
user-select:none;
}
See my example : http://jsfiddle.net/DoubleYo/RPv4q/
This solution is not cross browser but work fine with firefox and chrome/safari
EDIT : advanced user can copy your content with view the page source, make pdf or print your page, and some people mention firebug, fiddler.
If you send down any text the user will be able to see the source, so disabling copy and paste by any method will not really help stop the determined copier.
The most effective approach would be to render your text in to an image on the server and send down the image and not the raw text, but before you do that there are several downsides to consider: 1) You will require capacity on your server to generate the image. 2) The data load will be higher than just text and compresion will be less effective. 3) You may also loose some caching options.
Is there a particular reason you don't want the user to copy the text, perhaps if you can provide more details other approaches may be possible?
Try this
<html>
<head>
<script language="<strong class="highlight">javascript</strong>">
function onKeyDown() {
// current pressed key
var pressedKey = String.fromCharCode(event.keyCode).toLowerCase();
if (event.ctrlKey && (pressedKey == "c" ||
pressedKey == "v")) {
// <strong class="highlight">disable</strong> key press porcessing
event.returnValue = false;
}
} // onKeyDown
</script>
</head>
<body>
<form name="aForm">
<input type="text" name="aText" onkeydown = "onKeyDown()">
</form>
</body>
</html>
When someone visits your website they receive the html/css/images/JavaScript that makes up the bulk of your site. So they already have your Content, as most browsers cache this too, to allow quicker browsing.
Read more on HTTP here - http://www.http.header.free.fr/http.html
So it is not quite possible to totally stop anyone that know how the http protocol works. But what you can do is to maybe listen for right clicks and stop normal end users from right clicking and saving a image etc. You can get a snippet here - http://www.dynamicdrive.com/dynamicindex9/noright.htm
But if you are talking about protecting images/files that are selling please have a look at Protect html/php/image files from tracking as it then applies to your problem.
You can add to your body tag like so:
<body onselectstart="return false">
This is Internet. You can't completely protect the content of the page.
But you can difficult this task for the user.
You can too handle keyboard and mouse inputs, like Ctrl+C or right click of the mouse.
But remember that the user can always see the source code of the page, copy it and paste on a HTML editor.
You can make your site in Silverlight or Flash, but this will "disable" search engines indexing.
convert your page into a image
You can disable the selection, and with out selection you do not have copy/paste, however I suggest do that only on some parts of your page because is frustrate for the user.
This is the simple code that you can do that, eg, if you have a div with id="notme", run the disableSelOnThis("notme");
function disableSelOnThis(IdName) {
var oElem = document.getElementById(IdName);
if (oElem)
disableSelection(oElem); }
function disableSelection(element) {
element.onselectstart = function() {
return false;
};
element.unselectable = "on";
element.style.MozUserSelect = "none";
element.style.cursor = "default";
}
The code was from : http://ajaxcookbook.org/disable-text-selection/ , but its seams that this site is not longer live.
Of course without javascript enable this is not working and everything ChrisF says still stands.
Just copy and Paste the below javascript in your webpage:
<script language="javascript" type="text/javascript">
function disableselect(e) {
return false
}
function reEnable() {
return true
}
document.onselectstart = new Function("return false")
if (window.sidebar) {
document.onmousedown = disableselect // for mozilla
document.onclick = reEnable
}
function clickIE() {
if (document.all) {
(message);
return false;
}
}
document.oncontextmenu = new Function("return false")
var element = document.getElementById('tbl');
element.onmousedown = function () { return false; } // mozilla
</script>
Note:If the above code not works for Firefox then add style="-moz-user-select:none" in the body tag which needs to be restricted alongwith the above code.
I'm trying to make a proof of concept website, but I want perfect degradation. As such I'm going to code the website in plain XHTML first and then add classes & ids to hook them in jQuery.
One thing I want to do is eventually enable Ajax xmlhttprequest for all my links, so they display in a viewport div. I want this viewport to be a "universal" dump for any xmlhttprequest from multiple external pages.
I was wondering if I'm able to hardcode something like:
<a href="blah.html" class="ajax">, <a href="bleat.html" class="ajax">
etc. So as you can see, I give all link tags that I want to call Ajax requests from with the class ajax. In my JS based on jQuery, I want to be able to code it such that all positive ${"a").filter(".ajax") will automatically load their respective hrefs [variable] as a ajax request.
Please help. I'm a n00b.
With your example, you should be able to do:
$('.ajax').click(function () {
// Your code here. You should be able to get the href variable and
// do your ajax request based on it. Something like:
var url = $(this).attr('href');
$.ajax({
type: "GET",
url: url
});
return false; // You need to return false so the link
// doesn't actually fire.
});
I would suggest using a class different from "ajax" because it makes the code a little strange to read, because $('.ajax') could be misread as $.ajax().
The $('.ajax').click() part registers an onClick event handler for every element on the page with the class "ajax" which is exactly what you want. Then you use $(this).attr('href') to get the href of the particular link clicked and then do whatever you need!
Something like:
function callback(responseText){
//load the returned html into a dom object and get the contents of #content
var html = $('#content',responseText)[0].innerHTML;
//assign it to the #content div
$('#content').html(html);
}
$('a.ajax').click(function(){
$.get(this.href, callback);
return false;
});
You need to parse out everything that is outside of the #content div so that the navigation isn't displayed more than once. I was thinking about a regexp but probable easier to use jQuery to do it so I updated the example.