I have a page with few tabs. Data in each tab is ajax response once the user clicks tab.
Tab1 Tab2 Tab3
While coming to the page, we load Tabl with ajax response, in that serializing form.
After page loads, Editing form then checking is there any change to save the form data.
* Again serializing form and comparing old and new form.
It is working fine. But if i move to other Tab and come back to Tab1 serializing is not working as expected.
I kept alert and checked it. Orizinal form data serializing and new form also serializing and checking.
Even Data is same but
_sourcePage param is having different value.
I don't know why it is giving this strange behaviour.
Please help me.
Edit:
The code what i'm using is :
$(document).ready(function () {
originalSerializedForm = $("#Tab1").serialize();
});
function saveDataWhenFormChanged()
{
var newSerializedForm = $("#Tab1").serialize();
if(originalSerializedForm && newSerializedForm && newSerializedForm != originalSerializedForm){
alert('Original Form :'+originalSerializedForm+'\n'+'New Form :'+newSerializedForm);
$.ajax({
url : url,
data : newSerializedForm,
dataType: "html",
type : "POST",
beforeSend: function(){
openLoadingPopup();
}});
}
This happened due to zig-zag and not well formated html..
i was using form with in the other form.. which caused this..
i removed that.. it was working as expected..
Related
I have a ColdFusion page that has, among other things, forms that are built using DataTables.
This page manages a handful of things (documents, categories, doctypes, etc) and each tab has CRUD functionality going on.
Initially, on each tab, it simply displays the current set of (fill in the blank) but if you click the create/update links/icons, the form to do so pops up. Some of the form fields are actually lists of the others. For example, if I want to upload a new document, one of the form fields is the category for that document.
I get the information for that form field by using cfinvoke to a get function in a cfc, which returns as a query and I loop through, populating the dropdown.
My problem is this: If I go and create a new category on the category tab I need the dropdown of category choices to update over on the new document form. However, it's already been populated and won't recheck that info until I refresh the page and thus won't show my new category in the dropdown.
The way I see it, I need to reinvoke the CFC method, repopulating the query variable and then refresh the form to make it loop through the new data and fully populate the dropdown.
I've tried to call the cfinvoke and reset the form from within the callbacks section of the DTHelper() but that (kind of as expected) didn't work.
How would I force the refreshing of the data, and subsequently, the form when this all takes place using AJAX and the actual page never reloads? Or should I just be forcing a page reload in this situation? (which works, I tried that, but it's a page refresh)
So, my boss figured it out. You have to use drawCallback().
In my example it worked like so. First, give all your major category select boxes a class:
<select name="majorCategoryID" class="major-category-select">
...
</select>
Then modify the DataTable options for major category:
majorcat_dt = $("#majorcat-dt").DataTable({
ajax: "blah"
columns: [{ blah }],
drawCallback: function() {
/* remove all options from select boxes */
$(".major-category-select option").remove();
/* this is the crazy DataTables api call to get rows */
this.api().rows().data().each(function(row) {
$(".major-category-select").append("<option value='"+row.id+"'>"+row.name+"</option>");
});
}
});
This also removed the need for the cfinvoke in the first place since this also populates the dropdowns on page load as well.
Here is how I did something like that once.
javascript:
var minutes = 10;
var refreshInterval = minutes * 60 * 1000; // to get milliseconds
jQuery.fn.populateCensusDiv = function() {
$.ajax({
type:"POST",
url:"censusData.cfc?method=getCensusData",
cache:false,
success: function(msg) {
$("#census").html(msg);
}
});
setTimeout(function() {
$("#census").populateCensusDiv();
}, refreshInterval);
return this;
ColdFusion function
<cffunction name="getCensusData" access="remote" returntype="string"
//deleted code
returnFormat = "plain">
<cfscript>
var returnString = "";
</cfscript>
more code
<cfsavecontent variable="returnString">
more code
</cfsavecontent>
<cfreturn returnString>
</cffunction>
My context was an html table that got refreshed every 10 minutes. You can adapt it for your own needs.
I'm using jquery-ui tab example to add extra tabs. I changed that code to be able to add tabs that load a form via Ajax. I was able to create that just changing these:
var $tabs = $( "#tabs").tabs({
cache: true,
tabTemplate: "<li><a href='formularioAgricola.php' id='#{label}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>"
//ajaxOptions: a
});
So I changed the tabTemplate to load the same Form always.
My problem is that I'm not sure how to retrieve, either to tell that every tag from that form use jquery-ui stuff, like buttons, datepickers, etc.
In a regular form I would do something like:
$("#btnRevisar").button()
But when we talk about form load via Ajax it is different.
and also, how can I try to differ one form from other one, if they are all named with the same name, is it possible?
Thanks guys
Carlos.
Within the tabs docs page, tab titled "Events" there is a "load" event. The "ui" argument gives you access to an object that includes the current panel that is loaded. If you are using same ID on forms, beware that ID's must be unique in a page.
var $tabs = $( "#tabs").tabs({
cache: true,
tabTemplate: "<li><a href='formularioAgricola.php' id='#{label}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
/* add new option for load event*/
load: function( event, ui){
var $currTabContentPanel=$(ui.panel);
/* only look in currently loaded content for formClass*/
$currTabContentPanel.find('.formClass').doSomething()
}
});
I have a simple form with three textboxes and a <canvas> on the same page and I have to validate these three fields and then get the values (if validated) sent to a javascript function to draw a picture and some text inside the <canvas> element. The form and textboxes wouldn't have to disappear after the values were submitted because the user could try out different results with different values. I've done other forms before but never tried using Ajax. I know I could use a client-side validation and get the textbox values with jQuery but I have more server-side code running that would make use of these three values. How can I do this?
in your controller, create a method to handle the results. I assume that this is for logging only, and does not need to actually return data.
public useResults(string value1, string value2)
{
// ... Do something with the results
return Json(true);
}
In your view, work out a way to construct the url to the above action. Perhaps in a hidden field;
#Html.Hidden("useResultsUrl", Url.Action("useResults", "controllerName"))
Then in your javascript, attach a click event to the button, as you probably have already (to trigger your javascript task) and add in an ajax call.
Note that the following uses JQuery, but you could use microsoft AJAX if you preferred;
$(function () {
$("#button").click(function() {
$.ajax({
url: $("input[name='useResultsUrl']").val(), // Get the url from the hidden field
type: "POST",
dataType: "JSON",
data: $("input[type='text']").serialize() // Get the value of the text inputs and serialise them.
});
});
// ... do other stuff
});
Your View can make an ajax call to the server using JQuery - either using JQuery.post
or JQuery.ajax - you give the Url of the controller action to the JQuery method, and it will handle the AJAX call for you.
Then, in your controller action, you return a JsonResult - which serialize the data for you into JSON format:
e.g. return Json( model );
Finally, implement a success function in the JQuery Ajax call in your view - this wil have the data returned by the controller available for you to do whatever you want with.
This might sound like an odd scenario, but I've got two forms on one page. One is just posting back to itself. I made the second post to another action to keep the code cleaner. Maybe not the right choice...
The problem I'm having now is that if that second form doesn't validate, I redirect back to the page with the form but I don't know how to keep my form fields filled in with the original information the user entered. Is there a way to do that and keep posting to two separate actions, or do I need to just bite the bullet and have both forms post back to the same action and deal with the messy logic?
I would submit both forms to the same action. There really shouldn't be anything too messy about it. In each form include a hidden field to signify which form is being submitted.
Application_Form_Login:
/* other form elements */
$this->addElement('hidden', 'login', array(
'value' => 1
));
Application_Form_Register:
/* other form elements */
$this->addElement('hidden', 'register', array(
'value' => 1
));
Controller:
$loginForm = new Application_Form_Login();
$registerForm = new Application_Form_Register();
if($this->_request->isPost()) {
if($this->_request->getPost('login')) {
if($loginForm->isValid($this->_request->getPost())) {
// validated, redirect
$this->_helper->redirector('profile', 'user');
}
}
if($this->_request->getPost('register')) {
if($registerForm->isValid($this->_request->getPost())) {
// validated, proceed as needed
}
}
}
$this->view->loginForm = $loginForm;
$this->view->registerForm = $registerForm;
View:
echo $this->loginForm;
echo $this->registerForm;
With this type of a setup, if either of your forms fail validation, isValid() will preserve any data that has been entered and you still redirect on a successful validation of one or both of the forms.
Personally, I think that each form should post to its own controller, as you have. This keeps the code for processing that form in a single place. The issue here is that you want to return to the original page on failed validation. But why? Why not simply redisplay the form in the target controller, just like you would if there were a single form on the page?
For example, consider a login form that appears on every page of a sie (perhaps because it in the site template/layout). It posts to something like AuthController::loginAction(). If the login fails, then you don't typically send him back to the page from which he came. You leave him at the login page, with the form as pre-filled from the $_POST as you want it to be (probably a username, but not his password).
See this answer for a similar discussion.
Update: Had another thought in this. If you really want to handle the processing in two different controllers in order to keep him on the page from which he posted the form, at least extract that form processing out into an action helper. This way, you could at least keep that form-processing DRY.
Update: Rob Allen has just written a great blog post "A form in your layout" in which he describes a method that uses an action-helper with a preDispatch() method that instantiates and processes the form. Very nice.
How do you redirect? I don't see the problem if you just display the form page again. You can prefill you forms using Zend_Form::populate().
Well, I would just keep both forms submitting on the same page.
I don't see why your code should get any less readable. Learn how to use action helpers and your controllers will suddenly look extremely simple and readable:
public function indexAction()
{
$request = $this->getRequest();
// send forms to view, so we can print them
// but also so we can access them in action helpers
$this->view->form = $this->_getForm('Form1', '/');
$this->view->form2 = $this->_getForm('Form2', '/');
if ($request->isPost())
{
// process the first form
if (isset($_POST['form_submit_button']) && $this->view->form->isValid($_POST))
{
$this->_helper->form($this->view->form->getValues());
}
// process the second form
else if (isset($_POST['form2_submit_button']) && $this->view->form2->isValid($_POST))
{
$this->_helper->form2($this->view->form2->getValues());
}
}
Each form's processing would have its own action helper.
I'm using jQuery Form (http://jquery.malsup.com/form/) to get send data to a form - is there a way I can then, without refresh, put the results page that's generated by the form into a div on the page?
Any advice appreciated!
I would suggest not using that form plugin - it was made back in the days before there was an easy way to serialize form data using jQuery, and serves no real purpose any more. I would suggest something like this:
$("form").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$("#someDiv").html(data);
});
return false; // prevent normal submit
});
If you insist on using jQuery Form Plugin - which is NOT recommended -, you can set the target option to a selector of the element(s) you would like to fill up:
// prepare Options Object
var options = {
target: '#divToUpdate',
url: 'comment.php',
success: function(data) {
alert('Thanks for your comment!');
}
};
Take a look at http://jquery.malsup.com/form/#options-object for more info.
To prevent refresh, just make sure the form's onsubmit event returns false:
<form method="post" onsubmit="return false">