jQuery call php script which echos div but is not echoed - php

I am developing an upload script where you can upload an picture, which is directly previewed. After choosing the file it passes it to an php script which echos the picture. The jQuery in the first code inserts this into my preview . After the picture I am printing some input fields. In the input fields you can enter text you want to have on the picture, if you click preview it modifies the picture and shows it on the position the other picture was, but the input fields should stay there. My code:
<script type="text/javascript"><!--//--><![CDATA[//><!--
$j(document).ready(function() {
$j('#photoimg').live('change', function() {
$j("#preview").html('');
$j("#preview").html('<img src="loader.gif" alt="Uploading...."/>');
$j("#imageform").ajaxForm({
target: '#preview'
}
}).submit();
});
});
//--><!]]></script>
In the body I have this:
<div id='preview'>
</div>
I am echoing this:
echo "<img src='uploads/".$actual_image_name."' class='preview'><br />";
echo "</div><div id='preview3'>";
echo "Line 1 <input type='text' id='cardtext1' name='cardtext1' value='1'/>";
So I want to close the preview div in my echo and open another one that I can change the html code in the first div (with the picture) without any change to the input fields. The html code should be like:
<div id='preview'>
<img src='uploads/test.jpg' class='preview'><br />
</div> <====this one is missing
<div id='preview3'>
<input type='text' id='cardtext1' name='cardtext1' value='1'/>
</div>
The problem is, if I check the html code of the site it only shows the begin of the new but the closetag is not echoed. I also tried to put it in an php variable but also not working. Why is this? And how to fix?

Something looks wrong with your JavaScript code (the jQuery part).. It looks like there is an erroneous closing curly brace } here:
$j('#photoimg').live('change', function() {
$j("#preview").html('');
$j("#preview").html('<img src="loader.gif" alt="Uploading...."/>');
$j("#imageform").ajaxForm({
target: '#preview'
} // <-- right here
}).submit();
});
Looks like it should be:
$j("#imageform").ajaxForm({
target: '#preview'
}).submit();
Anyway, what you're doing by trying to dynamically close that div and inject a new one could be more tricky than its worth. I've never tried to do that but I feel like that would not be cross-browser compatible even if you got it working in, say, Firefox for example.
Instead of using $preview as your target, why not wrap it in another div container and use that:
<div id="container">
<div id="preview"></div>
</div>
Then, your jQuery would look like this:
$j('#photoimg').live('change', function() {
$j("#container").html('')
.html('<img src="loader.gif" alt="Uploading...."/>');
$j("#imageform").ajaxForm({
target: '#container'
}).submit();
});
In which case, the resulting PHP would end up like:
echo '<div id="preview">',
"<img src=\"uploads/{$actual_image_name}\" class=\"preview\"><br />",
'</div><div id="preview3">',
'Line 1 <input type="text" id="cardtext1" name="cardtext1" value="1"/>';

Related

previewing php/jquery form in fancybox, then submit or return to form

I've got a basic html/php form, with jquery validation. I want the user to be able to click a link that says "preview", have fancybox load up, and then I'll present a preview of the data, which means combining elements. For instance, the user can choose the background of the iframe. Here is the basics of my form -
<form action="loggedin.php" enctype="multipart/form-data" id="message_form" method="post">
<h4>Who would you like to send a message to?</h4>
<input type="text" size="35" id="recipient" name="recipient" value="Enter Name">
<h4>Choose A Background: </h4>
<input type="radio" value="plain" class="stationery_radio" name="stationery_radio" checked />
<label for="plain">Plain</label>
.....
And this is the info I want in my fancybox:
<a class="fancybox" href="#preview_message">Click Here To Preview Your Form</a>
<div id="preview_message" style="display:none;">
<h2>To: <?php echo ($message_form['recipient']) ?></h2>
.....
But I can't use the POST, as I haven't really submitted the form yet. How can I sent the data to my fancybox where the user can look at it, and either submit the form or return to edit? Thanks for any help.
What I would do is to create another .php file (e.g. preview.php) where you can (pre)submit the form via ajax. This file would basically echo the POST values of your form fields like $_POST['recipient'], etc.
Additionally, within the same file (preview.php) you may have some links to either submit the actual form or close fancybox.
Here is an example of the preview.php file
<?php
function check_input($data){
// sanitize your inputs here
}
$field_01 = check_input($_POST['field_01']);
$field_02 = check_input($_POST['field_02']);
$field_03 = check_input($_POST['field_03']);
// ... etc
?>
<div style="width: 340px;">
<h3>This is the preview of the form</h3><br />
<p>Field 01 : <?php echo $field_01;?></p>
<p>Field 02 : <?php echo $field_02;?></p>
<p>Field 03 : <?php echo $field_03;?></p>
<a class="submit" href="javascript:;">submit</a>
<a class="closeFB" href="javascript:;">back to edit</a>
</div>
notice style="width: 340px;" so fancybox will know what size of box to display (height would be auto)
Then in your main page, add the preview button
<a class="preview" data-fancybox-type="ajax" href="preview.php">Preview</a>
notice the data-fancybox-type="ajax" attribute, which tells fancybox the type of content.
Then the script to submit (preview) the form via ajax :
jQuery(document).ready(function ($) {
$('.preview').on("click", function (e) {
e.preventDefault();
$.ajax({
type: "POST",
cache: false,
url: this.href, // our preview file (preview.php)
data: $("#message_form").serializeArray(), // all the fields in your form (use the form's ID)
success: function (data) {
// show in fancybox the returned data
$.fancybox(data,{
modal : true, // optional (no close button, etc. see docs.)
afterShow: function(){
// bind click to "submit" and "close" buttons inside preview.php
$(".submit, .closeFB").on("click", function(event){
if( $(event.target).is(".submit") ){
$("#message_form").submit(); // submit the actual form
}
$.fancybox.close(); //close fancybox in any case
}); // on click
} // afterShow
}); // fancybox
} // success
}); // ajax
}); // on click
}); // ready
Of course, the DEMO at http://www.picssel.com/playground/jquery/postPreview_05Jun13.html.
NOTES:
this is for fancybox v2.1.4+
.on() requires jQuery v1.7+
You can use Jquery, to get the values, and put them into the fancy box...
A little like this...not quite, but you get the idea...
$('#preview_button').click(function(){
var msg = $('#recipient').val();
var bg = $('input:radio[name=stationary_radio]:checked').val();
$('h2#recipient').html(msg);
//and whatever you wanna do with the value of the bg
//probably apply some CSS on the fly to change the preview background?
$('#fancybox').show();
});
The fancybox show() is likely wrong, never used fancybox, so I dont know, but Im just using a generic, 'hidden div' show. I assume fancybox has its own API that is different, so just substitute...

Append instead of overwrite

I have this code that I'm working on, and I'm trying to append instead of overwriting the #preview div. I'm using JqueryForm plugin for jquery.
$(document).ready(function() {
$('#photoimg').on('change', function() {
$("#preview").html('<img src="load.gif" alt="Uploading"/>');
$("#imageform").ajaxForm({
target: '#preview'
}).submit();
});
});
I'm not really sure how I can achive that.
Later edit: I have this form:
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
Upload your image <input type="file" name="photoimg" id="photoimg" />
</form>
<div id='preview'>
</div>
When I browse and select an image the ajaximage.php verifies and upload the image and if succeed it will echo a message that is shown in #preview div. The problem is that its overwriting the div even if I use append.
You're close then:
$("#preview").append('<img src="load.gif" alt="Uploading"/>');
Here's the documentation.
Edit: based on your updated question, it appears that you may need to dynamically create a target for the ajaxForm plugin to use. Here's an example:
$(document).ready(function() {
$('#photoimg').on('change', function() {
$("#preview").html('<img src="load.gif" alt="Uploading"/>');
// create a dynamic target that we'll add to #preview
var $target = $('<div />').appendTo('#preview');
$target.attr('id', 'preview-target-' + Math.ceil(Math.random()*999999));
$("#imageform").ajaxForm({
// use the new target element's id for the ajaxForm target
target: '#' + $target.attr('id')
}).submit();
});
});
jmar is right.
Here is fill-in example command for it as for future reference.
$('#idoftarget').append('<div>new stuff</div>');

jquery removing all appended elements

I'm trying to code a todo list form. this form can contain unlimited rows. the rows each contain a text input field with 2 buttons beside it. 1 of the buttons adds a new row below, the second button deletes the row.
The problem is, when I click the add button a bunch of times, it removes ALL of the elements that were added below it when i click on the delete icon for that row.
I hope im making sense, maybe the code will explain whats going on.
Heres the PHP code for the todo-list form page:
<div class="table table-todo">
<?php include 'projects-add-task.php'; ?>
</div>
Here is the contents of projects-add-task.php:
<div class="field">
<input type="text" name="task[]" />
<img src="images/icon-todo-add.png" alt="" onmouseover="this.src='images/icon-todo-add-h.png'" onmouseout="this.src='images/icon-todo-add.png'" />
<?php if ($_GET['show_delete'] == 'yes') { ?>
<img src="images/icon-todo-delete.png" alt="" onmouseover="this.src='images/icon-todo-delete-h.png'" onmouseout="this.src='images/icon-todo-delete.png'" />
<?php } ?>
<div style="clear: both;"></div>
</div>
Here is the jquery that isnt working 100% correctly:
$('.todo-add').live('click', function (e) {
e.preventDefault();
$parent = $(this).parent('.field');
$.get('projects-add-task.php?show_delete=yes', function (data) { $parent.append(data); }, 'html');
});
$('.todo-delete').live('click', function (e) {
e.preventDefault();
$(this).parent('.field').remove();
});
I had to use live for the .todo-add icon because it was not working obviously for the newly appended rows. however im unsure if this is necessary for the .todo-delete icon, but i did it just to be sure.
Any help would be greatly appreciated with this issue.
I think you need after and not append:
function (data) { $parent.append(data); }
should be
function (data) { $parent.after(data); }
Also, live is actually deprecated now. You should be using on.
you are adding many divs with the class "field" and then asking jquery to delete them on the delete button.
you need to either have unique ID for each row and then delete that ID element os simply work witht he parent of the delete button, no need to specify the '.field' in the parent()
$('.todo-delete').live('click', function (e) {
e.preventDefault();
$(this).parent().remove();
});

How to display content within modal window?

I have a simple application here (QandATable2.php) where when the user clicks on the plus button, it will open a modal window and it displays the details which is stored in another page (previousquestions.php).
Now the problem I have is that if you straight away click on the "Search" button when the textbox is blank, you will see that it loads the page on its own page, displaying the message to enter in a phrase for the search and it also displays all of the features previously from the modal window into that page as well. This is incorrect.
What I want it to do is that if the user has clicked on the search button, then when it post's the form and outputs the message, it does it within the modal window, not on its own whole page. So does anyone know how this can be acheived?
The modal window I am using is known as SimpleModal and it's website is here
Below is the QandATable2.php code where it displays the plus button and where it opens the modal window, linking the content of the modal window to the previousquestions.php page:
<script type="text/javascript">
function plusbutton()
{
$.modal( $('<div />').load('previousquestions.php #previouslink') );
return false;
}
</script>
<h1>CREATING QUESTIONS AND ANSWERS</h1>
<table id="plus" align="center">
<tr>
<th>
<a onclick="return plusbutton();">
<img src="Images/plussign.jpg" width="30" height="30" alt="Look Up Previous Question" class="plusimage"/>
</a>
<span id="plussignmsg">(Click Plus Sign to look <br/> up Previous Questions)</span>
</th>
</tr>
</table>
Below is the previousquestions.php code, where it displays the details in the modal window and where the search feature is stored:
<?php
foreach (array('questioncontent') as $varname) {
$questioncontent = (isset($_POST[$varname])) ? $_POST[$varname] : '';
}
?>
<div id="previouslink">
<button type="button" id="close" onclick="return closewindow();">Close</button>
<h1>PREVIOUS QUESTIONS</h1>
<p>Search for a previous question by entering in a phrase in the search box below and submitting the phrase</p>
<form action="previousquestions.php" method="post">
<p>Search: <input type="text" name="questioncontent" value="<?php echo $questioncontent; ?>" /></p>
<p><input id="searchquestion" name="searchQuestion" type="submit" value="Search" /></p>
</form>
</div>
<?php
//...connected to DB
if (isset($_POST['searchQuestion'])) {
$questionquery = "SELECT QuestionContent FROM Question
WHERE(QuestionContent = '".mysql_real_escape_string($questioncontent)."')";
if (empty($questioncontent)){
echo "Please enter in a phrase in the text box in able to search for a question";
}
?>
You'll probably want to use AJAX, since you're already using jQuery you'll just need something like this:
// override the "default" form submitting behavior with a callback function
$("form").submit(
// this is the callback function for your form submit function.
function(e)
{
// this prevents the page from reloading -- very important!
e.preventDefault();
// get the search data from the input textbox
var s = $("input[name='questioncontent']").val();
// see annotation
$("#simplemodal-data").html("loading...")
.load("previousquestions.php #previouslink",
{
questioncontent : s,
searchQuestion : "Search"
}
);
}); // end submit wrapper
This will send the value to the server and load it in the div with id simplemodal-data
Annotation:
The last line in the code does several things. First, it replaces the simplemodal DIV with a "loading" message. At the same time, it makes a POST request to your previousquestions.php page. This part { questioncontent : s, searchQuestion : "Search"} is where the data from the form gets passed to the PHP page, (remember the variable var s assignment above. Lastly, the results from the previousquestions.php page should be loaded in the simplemodal-data modal window.
One thing that's missing is to add #previousquestions in the load method so that only a portion of your HTML document gets inserted in the modal. It's never a good idea to load an entire HTML page inside another HTML document, and "load" is designed to allow you to just pick the part of the document you want to insert, which is just that DIV.
I added "#previouslink" after the php filename. This is where the magic happens. The browser knows to extract that DIV from your PHP file and insert just that part on the page, no <head> <body> or any of the unneeded markup.
You can achieve what you're looking for by using AJAX to submit the form instead of using the default behavior where the page reloads with the new content. You can't use modal.load because you need to POST data in the request in order to get the appropriate response.
However, when using AJAX to post your data, you can take the response as HTML and add that HTML to a DIV on your page, and then invoke the SimpleModal command on that DIV container.
First, modify the submit button on your form so that it's type="button" instead of type="submit". This will prevent the form from submitting and redirecting the page. Alternatively, you could add event.preventDefault(); and return false to the form submit click handler (see the second step), but it's probably easier to try this method while you're making the changes:
Step 1:
<!-- change type to button -->
<input id="searchquestion" name="searchQuestion" type="button" value="Search" />
Step 2:
Create a handler for the form button, which uses serializeArray to serialize the form into a string and then POST it to the server. In the success callback handler, you'll then take the HTML response and replace the content in the modal window with the new HTML. This also catches errors, if any, and alerts them and writes them to the console:
$('form[type="button"]').click(function() {
var dataString = $('form').serializeArray();
$.ajax({
url: "/previousquestions.php?t="+new Date().getTime(),
type: "POST",
data: dataString,
context: document.body,
success: function(data){
alert(data); // results from server, either the HTML page, or JSON/XML
$('simplemodal-data').html(data); // if HTML, just insert into div#results
},
error: function(jqXHR, textStatus, errorThrown) {
if(window.location.hostname == "localhost") {
alert("Error submitting the form :: " + textStatus + " : " + errorThrown);
}
console.error("Error submitting the form :: " + textStatus + " : " + errorThrown);
}
});
});
Step 3:
Lastly, be sure that your previousquestions.php code returns only a partial HTML document, not a full HTML document. Since you're injecting HTML into an existing page, you don't need the <html>, <head>, or <body> sections. These will just cause your page to not validate, and may cause undesired behavior in legacy browsers. Here is an example of what your response might look like:
<div id="previouslink">
<button type="button" id="close" onclick="return closewindow();">Close</button>
<h1>PREVIOUS QUESTIONS</h1>
<p>Search for a previous question by entering in a phrase in the search box below and submitting the phrase</p>
<form action="previousquestions.php" method="post">
<p>Search: <input type="text" name="questioncontent" value="test" /></p>
<p><input id="searchquestion" name="searchQuestion" type="submit" value="Search" /></p>
</form>
</div>
<p>
Your Search: 'test' </p>
<p>Number of Questions Shown from the Search: <strong>0</strong></p><p>Sorry, No Questions were found from this Search</p>
I have found out from an answer on another page to a similar question to this that like Bergi has stated, it is easier using an iframe than using ajax to keep content displayed within a modal window. So the best answer for this question is below where it shows how an iframe is used for the question above:
function plusbutton() {
// Display an external page using an iframe
var src = "previousquestions.php";
$.modal('<iframe src="' + src + '" style="border:0;width:100%;height:100%;">');
return false;
}

jQuery+AJAX delete anchor not working

Hi I'm using jQuery and Codeigniter. I'm creating a simple todo list that can add delete entries using ajax.
The problem is whenever I click on my delete anchor, it won't delete the entry. The adding of the entry feature works BTW.
Here's my code:
todo_view.php
<html>
<head>Todo List</head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#submit').click(function() {
var msg = $('#message').val();
$.post("<?= site_url('todo/add') ?>", {message: msg}, function() {
$('#content').load("<?= site_url('todo/view/ajax') ?>");
$('#message').val('');
});
});
$('a.delete').click(function() {
var id = $('input', this).val();
$.post("<?= site_url('todo/delete') ?>", {todoid: id}, function() {
$('#content').load("<?= site_url('todo/view/ajax') ?>");
});
});
});
</script>
<body>
<div id="form">
<input type="text" name="message" id="message" />
<input type="submit" name="submit" id="submit" value="Add todo" />
</div>
<div id="content">
<?php $this->load->view('message_list'); ?>
</div>
</body>
</html>
message_list.php
<ol>
<?php foreach ($todolist as $todo): ?>
<li>
<?php echo $todo->todo; ?>
<input type="hidden" value="<?=$todo->todoid ?>" />delete</li>
<?php endforeach; ?>
</ol>
Why doesn't it work?
First and foremost - to track GET/POST headers and values you should start using Firebug (an extension for Firefox). Really makes your life easy to terms of debugging ajax calls and responses.
Next (somewhat on the lines of what alimango mentioned)... the most likely cause is that the message list is being loaded AFTER your main page's DOM has already loaded. jQuery won't automatically bind the click event to elements added later. Your click binding routine has to be called AFTER the message list has been added to the DOM. Now this isn't always possible... as your list is being fetched / altered dynamically.
One solution is to use the live() bind event function that has been introduced since jQuery 1.3. This helps binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events. Fore more information, see http://docs.jquery.com/Events/live#typefn
Second solution is to use, LiveQuery - a jQuery plugin which "utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated." You can grab it from http://plugins.jquery.com/project/livequery
Cheers,
miCRoSCoPiC^eaRthLinG

Categories