I am using a code snippet that I found to display a multipage form using visibility hidden.
There is a very good possibility that all of my problem stems from this method. That resource was from here:
http://www.devx.com/webdev/Article/10483/0/page/2
It is a fairly straightforward way to display multiple pages of a form...it probably was never intended to be able to allow printing.
<html>
<head>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script language="JavaScript">
$.getScript("printThis.js", function(){
});
var currentLayer = 'page1';
function showLayer(lyr){
hideLayer(currentLayer);
document.getElementById(lyr).style.visibility = 'visible';
currentLayer = lyr;
}
function hideLayer(lyr){
document.getElementById(lyr).style.visibility = 'hidden';
}
function showValues(form){
var values = '';
var len = form.length - 1; //Leave off Submit Button
for(i=0; i<len; i++){
if(form[i].id.indexOf("C")!=-1||form[i].id.indexOf("B")!=-1)
continue;
values += form[i].id;
values += ': ';
values += form[i].value;
values += '\n';
}
alert(values);
}
</script>
<style>
body{
font: 10pt sans-serif;
}
.page{
position: absolute;
top: 10;
left: 100;
visibility: hidden;
}
</style>
</head>
<body>
<form id="multiForm" action="App1.php" method="POST" action="javascript:void(0)" onSubmit="showValues(this)" id="app">
<div id="page1" class="page" style="visibility:visible;">
Applicant Name: <input type="text" size="50" name="name1" >
</form>
<p><input type="button" id="C1" value="Continue" onClick="showLayer('page2')"></p>
</div>
<div id="page2" class="page">
This is Page 2
<br>
<input type="button" id="B1" value="Go Back" onClick="showLayer('page1')">
<input type="button" id="B2" value="Print App" onClick="$('#page1').printThis({})">
<br><br>
</div>
</form>
</body>
</html>
The "Print App" button is properly calling the printThis plugin. However, I get no content from the page1 DIV section. All that is printed is the normal header portion (Page 1 of 1) in the upper right and about:blank in lower left and date in lower right of pageā¦no content, which with my sample file should be Applicant Name input box.
I assume that this is because the DIV for page1 is set to "hidden" while the content of page2 is being displayed. If I substitute "page2" in the button call then I get the content from page2 as expected.
So...I guess what I am after is a way to temporarily change the DIV being referenced in the printThis button call to be visible just long enough to perform the page print.
Any ideas?
I'm the plugin author - you need to incorporate the print media query into your css.
This would also help users that select file > print or control + P, as it will show all form elements.
The print media query allows you to make styling changes specifically for the printed page.
Example:
#media print {
#page1, #page2 {
display: block;
visibility: visible;
position: relative;
}
}
You include this in your css.
Additionally, based on your above code - you have css and javascript inline in your page. You should consider moving both to an external files, for maintenance and improved code standards.
printThis won't work with your current setup, because the plugin looks for the container (selector) you have specified and any linked css in the head of the document.
So for the above, you can do the following:
<!-- move all of this to the bottom of the page for performance -->
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="printThis.js"></script>
<script type="text/javascript" src="myJavascript.js"></script>
<!-- the above file is your javascript externalized, remove $.getScript, wrap in $(document).ready() -->
Then put this in your head:
<link type='text/css' rel='stylesheet' href='style.css'>
<!-- contains your css from the page, including the print media query -->
Related
I'm currently trying to dynamically add a new textAngular when clicking on the "Add" button.
As the first textAngular element is already present in the HTML page, the initialisation works fine using wysiwyg function and I'm able to use the toolbar and see the result in the corresponding textarea.
When I click on the "Add" button, I would like to have another textAngular editor along with its corresponding textarea, which I manage to have and to initialise but as soon as I do this the previous textAngular editor doesn't work and isn't linked to its textarea anymore. The toolbar is also unclickable.
I get the following result :
Here's the code of the index.html page :
<body>
<div id="mainContainer">
<div ng-app="textAngularTest" ng-controller="wysiwygeditor" class="container app">
<div name="cours" id="textbox1">
<h3>TextBOX 1</h3>
<div text-angular="text-angular" name="htmlcontent" ng-model="htmlcontent" ta-disabled="disabled"></div>
<h3>HTML BRUT 1</h3>
<textarea ng-model="htmlcontent" style="width: 100%"></textarea>
<br>
<button id="btn1" onclick="displayEditor()">Add</button>
</div>
</div>
</div>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-sanitize.min.js'></script
<script src='https://cdnjs.cloudflare.com/ajax/libs/textAngular/1.1.2/textAngular.min.js'></script
</body>
<!-- partial -->
<script src="./textbox.js"></script>
The style.css:
.ta-editor {
min-height: 300px;
height: auto;
overflow: auto;
font-family: inherit;
font-size: 100%;
}
And here is the code of textbox.js :
angular.module("textAngularTest", ['textAngular']);
function wysiwygeditor($scope) {
console.log($scope);
$scope.orightml = 'Hello';
$scope.htmlcontent = $scope.orightml;
$scope.disabled = false;
};
function displayEditor() {
var number = Math.random();
document.getElementById("mainContainer").innerHTML += '<div ng-app="textAngularTest' + number + '" ng-controller="myController' + number + '" class="container app" id="mainContainer' + number + '"><h3>TextBox2</h3><div text-angular="text-angular" id="htmlcontent" name="htmlcontent" ng-model="htmlcontent" ta-disabled="disabled"></div><h3>HTML BRUT 2</h3><textarea ng-model="htmlcontent" style="width: 100%"></textarea>';
angular.module('textAngularTest' + number, ['textAngular'])
.controller('myController' + number, function ($scope) {
$scope.orightml = 'Hey';
$scope.htmlcontent = $scope.orightml;
});
angular.bootstrap(document.getElementById('mainContainer' + number), ['textAngularTest' + number]);
}
Explanation of the code : When I click on the "Add" button, I build the HTML of the new textAngular editor and its textarea giving them unique attributes so they are independant with the previous ones. When I add this new HTML content on the DOM, I initialise the new angular module with its own controller. But as soon as I do this and as I said it above, the previous textAngular editors don't work anymore.
Does anyone know how to reach that goal and initialise multiple textAngular editors without breaking the previous ones ?
I have a page which has a lot of buttons. What I need to do is to show a div near the button. I tried this:
<style>
#noteDiv {display:none; position: absolute; background-color: white; border: 1px solid blue;}
</style>
<script>
function showNote(e) {
var x = 0, y = 0;
if (!e) e = window.event;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else if (e.clientX || e.clientY) {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
document.getElementById("noteDiv").style.display = "block";
document.getElementById("noteDiv").style.left = (x)+"px";
document.getElementById("noteDiv").style.top = (y-350)+"px";
}
function hideNote() {
document.getElementById("noteDiv").style.display = "none";
}
</script>
<body>
<?php
echo "<button type ='button' id = 'noteButton'>Note</button>";
echo "<script>document.getElementById('noteButton').onclick = showNote;\n";
echo "</script>";
?>
</body>
<div id='noteDiv' >
<div ><span onclick="hideNote()">Close</span></div>
<br clear="all">
<div id='noteContent' style='max-height: 30em'></div>
</div>
It does work. But sometimes the page will show one more div on top of the page, like a warning message, and thus the noteDiv's position will be far from the buttons to which it should attach.
My thinking is to get the position of the buttons, and send the x, y values of the button position to the function showNote(), from there show the noteDiv. I don't know if this idea is reasonable and how to get and transfer the current clicked button's position to javascript?
Any suggestions and hints will be appreciated!
From the beginning.
Load javascript on top of your page is a very bad idea. I'll let the tons of web articles to explain you why. Just to say one reason, the js files are downloaded before the html is rendered (depending on the browser), resulting in a slower rendering of the page.
About your approach:
Three words: separation of concerns. Positioning dom elements is not what belongs to javascript (except some very rare occasions).
Styling the DOM, which comprehends positioning of the objects, belongs to the Cascading Style Sheet, also known as CSS.
So if something is not rendered in the right way, don't try to fix it with javascript. It will only drives you to enormous headaches.
For a better answer, please provide a code that can show us the error.
UPDATE
Here is a working example (probably not optimised) of what you are maybe trying to achieve. Please, please, please, please... read a book about html, css and js. It's totally worth it. I didn't use php, didn't need it.
Just for the records, the general structure of an html page I personally use is like this one:
html
head
title
meta
styles link
styles sections
js **LIBRARIES** which need to be loaded on **TOP**
google analytics
body
html content
js **LIBRARIES** which need to be loaded on **BOTTOM**
js scripts
And for your sanity, and of the people who helps you, indent correctly (it's also a sign of respect to the people who are reading your code).
Here is the code with the snippet:
function toggleNote(id) {
var noteParent = document.getElementById(id);
var note = noteParent.querySelector('.note');
var display = "none";
if (note.style.display == "none" || note.style.display == "" ) {
display = "block";
}
note.style.display = display;
}
.note {
display: none;
position: relative;
background-color: white;
border: 1px solid blue;
}
.noteContent {
max-height: 30em
}
<body>
<div class="buttonContainer" id="note0">
<button id='noteButton' onclick="toggleNote('note0')">Note</button>
<div class='note'>
<div>
<button onclick="toggleNote('note0')">Close</button>
</div>
<br clear="all">
<div class='noteContent'>It's something!</div>
</div>
</div>
</body>
All the HTML like <button> <div> <span> <ul><li> <table> etc MUST be inside the <body> </body> tag:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<!-- you can include css and javascript here -->
<!-- but best place to include javascript ist at the bottom -->
<!-- see last comment -->
</head>
<body>
<?php echo '<button type="button" id="noteButton">Note</button>'; ?>
<!-- best place to include javascript or echo them with PHP what ever
right before the closing body tag -->
</body>
</html>
You are echoing a <button> via PHP before the opening <body> tag which is wrong. Try use something like firebug and https://validator.w3.org/
I am making a try it yourself HTML and CSS program, like you would see on w3schools or other websites. I was wondering if there was a way to make another button that would just display the HTML and ignore the CSS instead of having to have the user type in both. Here is the code that I have, so I still want to make a toggle button that toggles the CSS off and on, but I am unaware on how to do this.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style> textarea {
height: 100px;
width: 1000px;
} </style>
</head>
<body>
<form id='assignment5' method="post" action="assignment5.html">
<table>
<tr><td><textarea name="html">Enter HTML Here</textarea></td></tr>
<tr><td><textarea name="css">Enter CSS Here</textarea></td></tr>
</table>
<input type="submit" value="Launch">
<input type="reset">
</form>
<div id='content'></div>
</body>
</html>
<script>
$(document).ready(function(){
$('#assignment5').submit(function(e){
e.preventDefault();
$('#content').html( $(':input[name=html]').val() );
$('head').append( '<style>' + $(':input[name=css]').val() + '</style>' );
});
});
</script>
Yes, it is possible..
First, you just have to create an element to listen to for that purpose..
something like(using a separate button):
<input type="button" value="Html only" id="html_only">
then this jQuery script to handle the click event:
// this will just output the html ignoring the css textarea
$('#html_only').click(function(e){
$('#content').html( $(':input[name=html]').val() );
});
or this way (using a checkbox that acts like a switch):
<input type="checkbox" name="css_switch" id="css_switch"/> apply CSS?
and change your script to this:
$('#assignment5').submit(function(e){
e.preventDefault();
if($("#css_switch").is(":checked")){
// output from html textarea only
$('#content').html( $(':input[name=html]').val() );
}
else{
// output from html textarea and append input from css textarea
$('#content').html( $(':input[name=html]').val() );
$('head').append( '<style>' + $(':input[name=css]').val() + '</style>' );
}
});
USING button DEMO
USING checkbox DEMO
I'm currently upgrading a WYSIWYG Rich Text Editor that was based on the DHTML Editor Control (DEC) to use the more modern editor controls in modern browsers. I'm using an iFrame with design mode turned on and a mixture of regular javascript and jquery.
One of my requirements is to insert html content (forms etc) into the iframe so that users can edit them. I have it working in FF + Chrome, but IE is proving a pain. My current code inserts the content at the start of the parent document and not the iframes, I'm using the selection.createRange() function that when used with DEC would insert the content either at the cursor if the control was selected or at the end of the document inside the editor if not.
Currently it only works when I select some text in IE. Heres my current code (apologies if it looks unformatted the firewall at work is blocking a lot of the css + js from stackoverflow), any ideas?
<html>
<head>
<title>Text Editor Test</title>
<style type="text/css">
.toolbar {background-color:#BFC193;width:500px;padding:5px;}
#insertForm {position: absolute;height:60px;width:200px;top:50px;left:50px;border:1pt solid black;background-color:#fff;padding:10px;}
</style>
</head>
<body>
<h1>MSHTML Text Editor</h1>
<form id="frmEdit">
<div class="toolbar" id="toolbar">
<input type="button" name="insertHTML" value="insert html" onClick="showForm();"/>
</div>
<div id="insertForm" style="display:none;">
Insert Content Form
<input type="button" value="OK" style="width: 80px" onClick="insertContent();">
</div>
<script type="text/javascript" src="jquery-1.6.4.js"></script>
<script type="text/javascript">
// functions to execute once the DOM has loaded.
$(document).ready(function() {
pageInit();
});
function pageInit() {
// create iframe
$('.toolbar').after("<iframe id='frameEdit' style='width:500px; height:400px' ></iframe>");
//insert delay for firefox + webkit browsers before turning on designMode open + close seems to do the job
document.getElementById('frameEdit').contentWindow.document.open();
document.getElementById('frameEdit').contentWindow.document.close();
document.getElementById('frameEdit').contentWindow.document.designMode='On';
}
function showForm() {
$('#insertForm').toggle();
}
function insertContent() {
// turn off form
showForm();
// set test content
var htmlContent = "<p>Insert Test</p>";
var doc = document.getElementById('frameEdit').contentWindow.document;
if (doc.selection && doc.selection.createRange) { // IE
var range = doc.selection.createRange();
range.pasteHTML(htmlContent);
} else { // FF
doc.execCommand('insertHTML', false, htmlContent);
}
}
</script>
</form>
</body>
</html>
Make your button unselectable to stop it nicking the focus from the iframe. You can do this in IE using uneselectable="on":
<input type="button" value="OK" unselectable="on"
style="width: 80px" onclick="insertContent();">
I printed to the screen 16 icons (little pictures).
Now I want to be able to select icons,
and when I press a button the selected icons ids will be sent in a form.
I saw in the net only checkboxes and lists multiselect,
what's the best way to do this?
(I'm pretty new to web design)
thanks ahead!
Although jQuery isn't in your tags, you should introduce yourself to jQuery. It'll make your life easier, for what you're trying to do. Here is the basic steps both if you use jQuery and if use just Javascript:
With jQuery
Give all your icons a class and each one a unique id:
<img src='icon1.png' data-iconID=2233 class='myIcons' />).
Then bind that class to a click event
$('.myIcons').bind('click', function() {
$(this).toggleClass('selectIcon');
});
Attach form submit function to onsubmit:
<form ... onsubmit="submitForm();">
Build submitForm function:
function submitForm() {
var csvIconIds = '';
$.each($('.myIcons.selectIcon'), function (index, value) {
csvIconIds += $(value).attr('data-iconID');
});
//submit scvIconIds here along with other form data (ajax?)
}
With Javascript
Similar as above but way more complicated...
To toggle classes see this thread: How to add/remove a class in JavaScript?
To getting attributes by class see this site: http://www.actiononline.biz/web/code/how-to-getelementsbyclass-in-javascript-the-code/
This could be a way using just plain Javascript or jQuery. I prefer the jQuery version, since it separates the click handler from the markup, instead of using inline onclick handlers, which are in general discouraged.
What this does is use an input element array, which you can create by adding [] to the element name. This same technique can be used on SELECTs and other elements, since it signals to the server that an array has been submitted, as opposed to value known by a single key.
<html>
<head>
<style type="text/css">
div img {
cursor: pointer;
border: 1px solid #f00;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<script>
function setFormImage(id) {
if (id != '' && !document.getElementById('input_'+id)) {
var img = document.createElement('input');
img.type = 'text';
img.id = 'input_'+id;
img.name = 'images[]';
img.value = id;
document.imageSubmit.appendChild(img);
}
}
$(document).ready(function(){
$('#jqueryimages img').click(function(){
setFormImage(this.id);
});
});
</script>
</head>
<body>
<pre><?php
if (count($_GET['images'])) {
print_r($_GET['images']);
}
?></pre>
<div style="float: left; width: 49%;">
<h1>Plain ol' HTML</h1>
1. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-1" onclick="setFormImage(this.id)"/>
<br/>
2. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-2" onclick="setFormImage(this.id)"/>
<br/>
3. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-3" onclick="setFormImage(this.id)"/>
<br/>
4. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-4" onclick="setFormImage(this.id)"/>
</div>
<div id="jqueryimages" style="float: left; width: 49%;">
<h1>jQuery</h1>
5. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-5"/>
<br/>
6. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-6"/>
<br/>
7. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-7"/>
<br/>
8. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="img-8"/>
</div>
<h1>Form Submit</h1>
<form name="imageSubmit" method="get">
<input type="submit" value="View Selected"/>
</form>
</body>
</html>
try this
var idArray = [];
$("#container-id img").each(function(index,value){
idArray.push($(value).attr("id"));
});
//do anything with the array