Facebox adding commas to input - asp.net

I'm using a facebox to display a form inside a lightbox, nothing too exciting (just a couple of datepickers, some textboxes and a checkbox).
However, I'm having issues with the postbacks, whenever I post back from the facebox it adds a ',' to the start of the input (so "rabbit" becomes ",rabbit")
Now, I saw that there was the same issue with the modalpopup extender from the ajaxcontroltoolkit, so I assume it's a common issue.
Can anyone either explain why this is happening, or tell me how to fix it? provide a decent way of fixing this? I have actually done it, and it works very nicely, but I don't really want to answer my own bounty question so someone else give it a go!
Cheers, Ed
EDIT
See attached answer for a correct solution (I fixed this eventually but didn't want to ruin the bounty question so left the answer until afterwards).

Why don't you trim the output? simply remove the ',' for each string

I have never programmed in ASP.NET or used facebox for that matter of fact, but here's a couple of solutions from my little research that might work.
There is a reveal function in the facebox source where the actual cloning is done:
reveal: function(data, klass) {
$(document).trigger('beforeReveal.facebox')
if (klass) $('#facebox .content').addClass(klass)
$('#facebox .content').append(data) // <--- This does the cloning
The extra comma is obviously from the original form field that has been repeated. You could bind a click() function to the submit button that submits the form and in that function remove one of the clones. Since this function should run before the form data is processed, the duplicates should be taken care of.
$("#my-submit-button").click(function() { $('#facebox .content').empty(); }
If that doesn't work, then this surely will. Facebox has a bunch of hooks to run your code after various events. One of the hooks is reveal.facebox or afterReveal.facebox. Since the cloning is done on reveal, you would have to bind a custom function to run at this event, and in that function change the id/names of all elements. Append a random word like _temp or something for each element. Not the exact code, but I hope you get the idea.
(document).bind('reveal.facebox', function() {
$("#facebox .content > *").each(
// change the id's/name's
);
});
Edit:
Looking at the html for Facebox examples, it looks like it lives inside its own <div> and copies anything that has to be shown within that div. So the structure of a sample facebox page could look like:
<html>
..
<form runat="server">
<div id="myForm">
// original form controls go here, probably hidden
<input id="theId" type="text" value="" />
</div>
<div id="facebox">
...
<div class="content">
// the original form is copied inside this space and then displayed
// this is the one the user interacts with and makes changes to
<input id="theId" type="text" value="new value" />
</div>
...
</div>
</form>
..
</html>
So based on this structure and example, the input box with id=theId appears inside div#myForm and div#facebox. div#facebox is the one with the updated values that we need.

Ok, Here's how I fixed it:
changing
function fillFaceboxFromHref(href, klass) {
....
if (href.match(/#/)) {
var url = window.location.href.split('#')[0]
var target = href.replace(url, '')
$.facebox.reveal($(target).clone().show(), klass)
....
}
to
function fillFaceboxFromHref(href, klass) {
....
if (href.match(/#/)) {
var url = window.location.href.split('#')[0]
var target = href.replace(url, '')
$.facebox.reveal($(target).show(), klass)
....
}
will stop it cloning the input and instead use the actual div.
Then, it's simply a case of re-appending the inner content to the #aspnetform (or #body as it originally used [you have to change that to allow asp.net postbacks]) before it's cleared in the close.facebox binding, like so:
$(document).bind('close.facebox', function() {
/// two added lines to add the content back to the #aspnetForm, with display:none; (i.e. invisible)
$('#facebox .content').children().css({'display' : 'none'});
$('#aspnetForm').append($('#facebox .content').html());
/// extra line to make sure there's no flashing effect as the facebox closes: the content is still in there too!
$('#facebox .content').children().css({ 'display': 'block' });
....
This will now use the original div as the content, avoiding the comma problem. However, if you wanted to use a div that is visible on the page originally then some extra twiddling would be needed in the close.facebox binding.

Related

How to wait until HTML file loads?

In a page I am working on I replace the HTML code in a DIV with different HTML, then using Javascript I insert additional HTML into a DIV the new code using innerHTML.
If that is confusing, the original HTML contained a form, the HTML that replaced it contains the response to the form's Submit, and the code I want to insert is the information from the form.
This seemed to work as long as I had alert code in the script, which I use to check the progress as I debug this. Once I removed the all of alert lines the insert would fail. I figure it has to do something with the asynchronous nature of page rendering, so I think I need to find a way to make sure the new HTML code has loaded before I try writing to the DIV it contains.
In the code below the script fails at show_member_info unless I uncomment the preceding alert line.
function handle_join(X)
{
do_trace('handle_update');
get_member_info();
send_emails(X);
do_trace('clear content');
document.getElementById("members_content").innerHTML='';
document.getElementById("members_image").innerHTML='';
do_trace('load content');
Load_HTML('members/joinConf.html','members_content');
// alert('show_member_info');
show_member_info();
show_trace();
}
How do I determine when the new HTML has loaded and is ready to be manipulated?
Thanks, Mike
The question is a bit dry, but from what i can understand the problem is that you are not awaiting Load_HTML and that's causing some issue with show_member_info.

Using bootstrap-tagsinput plugin in meteor

In my meteor project I am using the bootstrap-tagsinput plugin:
http://timschlechter.github.io/bootstrap-tagsinput/examples/
I use it in the 'typeahead' mode, and so it requires initialization as in:
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
<script>
$('input').tagsinput({
typeahead: {
source: function(query) {
return $.getJSON('citynames.json');
}
}
});
</script>
I can't figure out what is the best way to integrate it with meteor -- so I'm asking for advice.
I've tried several approaches:
(1) Put the initialization code in the .created of the template containing the input element:
<template name="hello">
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
</template>
template.hello.created = function () {
$('input').tagsinput({...});
}
This seems natural. But, when the template gets re-rendered, the initialization data is lost and the input element does not behave as a tagsinput.
(2) Same as (1) but add the {{#constant}} directive. The {{#constant}} directive prevents re-rendering according to meteor docs. The plugin should just work if it is init once and never re-rendered:
(btw, there's a reason for the added div, see further on:)
{{#constant}}
<div>
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
</div>
{{/constant}}
This fails with:
"Exception from Deps recompute: Error:
An attempt was made to reference a Node in a context where it does not exist"
The exception stack was useless (mostly 'spark' code), so I ended up abandoning this path (but I suspect this is still the best way, if only I can get it to work).
(3) Initializing the tagsinput in the .rendered function:
template.hello.rendered = function () {
$('input').tagsinput({...});
}
This also fails, because the plugin accepts initialization exactly once. A second initialization will not work: it expects the tagsinput() arg to be a function property name and tries to execute it (or something along these lines).
(4) I thought I'd take (3) further and outsmart it by removing the initialized data:
template.hello.rendered = function () {
$('input').removeData('tagsinput');
$('input').tagsinput({...});
}
This clears data['tagsinput'] at the input element and allows for repeated tagsinput initializations. Once data['tagsinput'] is non-existent, the initialization goes through and recreates it.
This trick almost solved it, except for a small side-effect: an auto-generated div element lingers in the DOM. The way tagsinput plugin works is by adding a sibling div after the input element:
<input data-role="tagsinput" ... />
<div class="bootstrap-tagsinput">...</div> <-- auto-generated by tagsinput
Once solution attempt (4) runs, an occasional div as such will remain in the dom, along with the newly generated div.
At this point I started feeling that this solution is not according to the meteor spirit, but I decided to try to get rid of the lingering div using:
template.hello.rendered = function () {
$('input').removeData('tagsinput');
$(".bootstrap-tagsinput").remove();
$('input').tagsinput({...});
}
This code gets the job done, but it's super hackish and it is likely to break when meteor or tagsinput are updated.
If any of you meteor-ninjas out there can tell the right way of initializing tagsinput, that would be awesome!
My fix with typeahead was wrapping all other reactive regions of template inside isolated regions: http://docs.meteor.com/#isolate
You must do in all of them.

Drupal views - splitting up the exposed form possible?

I need to display part of the exposed form in my page's sidebar, and the rest of the form and content in the $content area. There's really no good way that I can find to do this. I sort of got it to show up in a way by making a "block" view with "exposed form" set and then trying to only show the part that i needed through .tpl files. The problem is that then, when the submit button is clicked (the submit button is in the $content area), then the filters that are in the sidebar are not taken into account.
Some lateral thinking... Why not explore CSS-only options? You can place that form element playing with position:absolute ? Or (considering is a right-sidebar) float:right and then some negative right margin to push it to the sidebar? If you are using 960 grid system, play with pull and push classes.
First I am going to answer your question, then I will explain why you are asking the wrong question:
If you build the form outside of the formapi, you might have some luck. This will get upgly and will require you to take a lot of extra care about attack-vectors such as mass-assignment.
views_some_view.tpl.php:
<form name="input" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
my_custom_exposed_view.module:hook_block()
City:
That would make a form, which in most situations will start with <form>, have some input fields, then have a lot of random HTML, then some more input fields and then the closing .
As you may know, a <input type="submit" value="Submit" /> will only post everything of the form tags it is enclosed in. The submit button in the following HTML:
<form name="input_1" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
</form>
<form name="input_2" action="/link/to/view" method="get">
City: <input type="text" name="city" />
<input type="submit" value="Submit" />
</form>
will only send the City. These are not the droids you are looking for.
It will need to be one, big form, but since everything between form and /form is very dynamic, and contains a large quantity of HTML, including potential other forms, this is really not what you want. Moreover: a blocks appearance (shown/not-shown) is controlled completely independent of the content. You will need a lot of sturdy code to ensure the block a) never shows up when the starting form tag is not present, and b) the block will guaranteed to be shown when that opening form tag is present. Else you have not just invalid HTML, but broken HTML that will truly render your page unusable in most cases.
You simply don't want a part of the form in a block and the other part in the content.
However, you want it visualised as if one part is in the body, the rest in a sidebar.
The good news, is that with HTML presentation structure are independant. That is where your solution lies.
Give your form-fields good ids and classes. You could use a hook_form_alter to change existing forms, but you probably simply just want to create the HTML for that entire form yourself. The theme layer allows that.
Use CSS to pick out either single form-fields by ID and position:absolute them into the correct place. Or pick out classes of fields by CLASS and position:relative them into the correct place.
Make a simple identification-routine that allows adding a class to the body-tag. (see below).
Add some CSS to shift the sidebar lower, making space for the form-fields to be moved in, when that class is in the body-tag.
<body class="<?php print $splitform ?>">
function my_themename_preprocess_page() {
if ($GET['q'] == 'path/to/view') {
$vars['spliform'] = "splitform"
}
}
From the above explanation I am assuming that you are printing same form in block and in content area and you are hiding some part of form in page.tpl , if this is true then you can use hook_form_alter() in your custom module then
Store the value of the form element(present in block) in global variable.
Now use that global variable and set form element(present in content area, this form element is not visible to user).
Provide more information if you implemented other way.
Regards,
Chintan.
There is a related issue here:
https://drupal.stackexchange.com/questions/3827/multiple-copies-of-views-filter-form-exposed-filters
which describes how to duplicate your filters. However it seems like an ugly hack.
A bit cleaner seems this solution mentioned in #6:
http://drupal.org/node/641838#comment-3247748
Haven't tested it out, but it looks good.
It will still give you some overhead (duplicate views) but it might be the easiest way doing this using views.
On the other hand you might write a module and build your own custom filter block which hooks into your view. Here is a blog post about this:
http://www.hashbangcode.com/blog/creating-custom-views-filters-exposed-form-element-drupal-6-561.html
If you use something like context you could get the exposed filters block to display twice in the same page. You could then use CSS to hide the fields you don't want to do display in each form.
The fundamental problem you're having is that to have the two forms in different places, they'll each have their own form element - when a submit is triggered, only the form fields within the same form element are sent. You need to move them into one form, or rely on JavaScript to gather the fields from both forms and construct the post.
You could create the block as an empty div and have javascript from the main page populate it with the secondary filter form and whatever else you need in there. Again, you could use javascript to copy the form values from the block form to hidden fields in the main form on submit. That gives you all the control you need from one place (the node output). Only caveat is that it relies a lot more on javascript to join it all together.

Disable copying data from webpage

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 am trying to refresh a sidebar.php in wordpress on a form submit

I am trying to refresh a sidebar.php in wordpress on a form submit (that is in a widget on the sidebar.php).
I have video on the page and if the entire page refreshes, the video has to play from the beginning.
I need a solution to simply refresh the sidebar.php when someone submits the form ... I am not an expert php programmer so simple is best!
btw. I am using formidable plugin for the form.
thanks in advance!
Sounds like a job for ajax!
Now, you could do it from scratch, but that would be unnecessarily painful. Instead, I recommend including jquery into your page by adding this into your header
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
(which uses the latest version, which is hosted on google)
Now that you have jquery loaded, there are many easy ways to submit your data without interrupting the flow of things. Here is how I would do it (I am assuming that you are using method="post"):
Change your <input type="submit" > into a <button>, so clicking on it doesn't trigger the built-in form submit (which would interrupt your video).
Set the id attribute of your button to something so that you can reference it easily like <button id="mysubmitbutton">. (While you are at it, give id attributes to all the form fields you care about if you have not already so that you can reference them easily as well, like <input type="text" name="firstName" id="firstName"> instead of just <input type="text" name="firstName">)
Inside the <head> portion of your website, add some code that looks like something like this:
<script type="text/javascript">
//makes it so that it goes after the html document is ready for it
$(document).ready(function() {
//this ties a onclick event to your button you made
$("#mysubmitbutton").click(function(){
//when the button is clicked, it will asychronously post to where you want it to
$.post("urlthatwasinyouractionequalsattribute.php",
{
//put all your post variables here, referencing the ids you made earlier
firstName: $("#firstName").val(),
time: $("#time").val() //be sure you don't have a trailing comma on the last one
},
function(data) {
//data is whatever the other website sends back. do whatever you want here...
alert("Result: " + data);
});
});
});
</script>
Fire it up and it should work. Obviously, you will need to change the values so that it matches your form, etc.
Hope that helps! Please mark as answer if it did.

Resources