ajaxSubmit into current jQuery Tab - ajax

I know how to grab the index, but that doesn't appear to be what I need to post into the tab itself.
This is a continuation, but different question, from my previous post: Submiting jQuery form results back into dynamic tab
My tab form is submitting now with 100% success, internal to my jQuery validate, but I want my reply to appear in the tab it came from.
At the end of my jQuery validation I have:
submitHandler: function(form) {
var thisTab = $tabs.tabs('option', 'selected'); // what index are we?
var options = {
target: '#thisTab',
};
$(form).ajaxSubmit(options);
return false;
}
It's close, but what I'm doing is actually grabbing the index of the selected tab, this does not appear to be what I need for the ajaxSubmit to post into.

As I understand you want to set target to thisTab, but you are setting target as a jQuery selection string #thisTab,
this means target is the element with id "thisTab".
From Jquery Form Plugin API
target
Identifies the element(s) in the page to be updated with the
server response. This value may be specified as a jQuery selection
string, a jQuery object, or a DOM element. Default value: null
So you should set thisTab as the target.
Update : The main problem is that you are trying to set tab as target element, you should set the selectedPanel as target.
submitHandler: function(form) {
var thisPanel = $tabs.tabs('option', 'selectedPanel'); // what index are we?
var options = {
target: thisPanel,
};
$(form).ajaxSubmit(options);
return false;
}

Hum, maybe I wasn't clear and I'm not explaining it.
What I want is for the output of update.cfm to be shown in the same dynamic tab body that held the details I just updated. I tried what you suggested and all it does when I hit submit is blink. It does submit, I can use firebug to see the post and response, but the response is not shown. So I do want the tab as the target.
What you did do however is show me a new term "selectedPanel" that I did not know, and that lead me to this post which I had not seen before: How to get the selected tab panel element in Jquery UI Tabs?
And that led me to make the following change:
submitHandler: function(form) {
var selectedPanel = $("#tabs div.ui-tabs-panel:not(.ui-tabs-hide)");
var options = {
target: selectedPanel
};
$(form).ajaxSubmit(options);
return false;
}

Related

Why disabled fields are not providing values on clicking submit in mvc3?

I have used Ajax.BeginForm / Html.BeginForm for a view which sends an object to the controller on clicking submit. There are some telerik controls which are disabled conditionally. On clicking submit, the object is unable to retrieve the already existing value in the control since it is disabled. Hence object is made with null values. Any help?
Im using jquery to disable these telerik controls on loading the page.
Change.setDropDownValues = function () {
if (condition) {
$("#A").data('tDropDownList').enabled = false; $("#A").data('tDropDownList').disable();
}
}
else if (condition) {
$('#Pop').attr('disabled', 'disabled'); //text box
$('#ShortDesc').attr('disabled', 'disabled'); //textarea
$('#LongDesc').attr('disabled', 'disabled'); //text area
$('#Cont').attr('disabled', 'disabled'); //text box
$('#iDate').attr('disabled', 'disabled'); //datepicker division
$('#C').data('tDropDownList').enabled = false; //drop down list
$('#C').data('tDropDownList').disable();
}
};
Can anyone say how to remodify so that I can fetch the disabled field values?
That's how disabled inputs work. They never send the value to the server. You could use readonly instead if you want to prevent the user from modifying the value and yet send the old value to the server when the form is submitted.
you can use something like this
$(":disabled", $('#yourform')).removeAttr("disabled");
before submit.

jquery mobile ajax sends both GET and POST requests

Here is the problem:
By default jQuery Mobile is using GET requests for all links in the application, so I got this small script to remove it from each link.
$('a').each(function () {
$(this).attr("data-ajax", "false");
});
But I have a pager in which I actually want to use AJAX. The pager link uses HttpPost request for a controller action. So I commented the above jQuery code so that I can actually use AJAX.
The problem is that when I click on the link there are two requests sent out, one is HttpGet - which is the jQuery Mobile AJAX default (which I don't want), and the second one is the HttpPost that I actually want to work. When I have the above jQuery code working, AJAX is turned off completely and it just goes to the URL and reloads the window.
I am using asp.net MVC 3. Thank you
Instead of disabling AJAX-linking, you can hijack clicks on the links and decide whether or not to use $.post():
$(document).delegate('a', 'click', function (event) {
//prevent the default click behavior from occuring
event.preventDefault();
//cache this link and it's href attribute
var $this = $(this),
href = $this.attr('href');
//check to see if this link has the `ajax-post` class
if ($this.hasClass('ajax-post')) {
//split the href attribute by the question mark to get just the query string, then iterate over all the key => value pairs and add them to an object to be added to the `$.post` request
var data = {};
if (href.indexOf('?') > -1) {
var tmp = href.split('?')[1].split('&'),
itmp = [];
for (var i = 0, len = tmp.length; i < len; i++) {
itmp = tmp[i].split('=');
data.[itmp[0]] = itmp[1];
}
}
//send POST request and show loading message
$.mobile.showPageLoadingMsg();
$.post(href, data, function (serverResponse) {
//append the server response to the `body` element (assuming your server-side script is outputting the proper HTML to append to the `body` element)
$('body').append(serverResponse);
//now change to the newly added page and remove the loading message
$.mobile.changePage($('#page-id'));
$.mobile.hidePageLoadingMsg();
});
} else {
$.mobile.changePage(href);
}
});
The above code expects you to add the ajax-post class to any link you want to use the $.post() method.
On a general note, event.preventDefault() is useful to stop any other handling of an event so you can do what you want with the event. If you use event.preventDefault() you must declare event as an argument for the function it's in.
Also .each() isn't necessary in your code:
$('a').attr("data-ajax", "false");
will work just fine.
You can also turn off AJAX-linking globally by binding to the mobileinit event like this:
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Source: http://jquerymobile.com/demos/1.0/docs/api/globalconfig.html

TinyMCE not working in http request xhr ajax generated page

So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.

simulating the "add another item" ajax call in drupal 7 using jquery

I am trying to get jQuery to send a mousedown event to the Drupal 7 "add another item" button for a multi-value field, then wait until the ajax call has completed before filling in that new blank row with data from an element in a jQuery object (that has several elements). I need to use a loop to cycle through the elements (ingredients) in this jQuery object, but no matter what I try my page dies...
Currently, I have something like the following:
i = 0;
ingredients = newHtml.find('.recipe_ingredients > li');
ingredientsLength = ingredients.length;
$('#edit-field-ingredients-und-add-more').mousedown();
while(i < ingredientsLength) {
if ( document.readyState !== 'complete' ) {
// code to fill in the new blank row with data from 'ingredients'
$('#edit-field-ingredients-und-add-more').mousedown();
i++;
}
}
Because I don't yet know how to issue the ajax call myself using jQuery (or using Drupal) I've been trying to just check whether the call has completed by using .readyState and other hack-like methods. I'm just not sure what to try next!
Am I going about this the completely wrong way? Is there a straightforward way to make the "add another item" multi-value field ajax call using jQuery? Any help would be greatly appreciated...
I am not sure if there's a nicer way in Drupal 7, but in Drupal 6 you could use jQuery(document).ajaxComplete with the settings.url property to tell when a specific "Add another item" click had finished.
Start with:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
alert(settings.url);
});
}(jQuery));
Once you've identified the right settings.url for your field, change that to:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
if (settings.url == "the path from step 1") {
// Code to populate your fields here
}
});
}(jQuery));
And voila!
You might want to read the page by Jay Matwichuk where I originally learned this technique awhile back. All credit to him (and nclavaud for his comment there), really.

How to enable click in edit action button if new row is saved jqgrid

Edit formatter action button is placed to jqgrid column:
colModel: [{"fixed":true,"label":" change ","name":"_actions","width":($.browser.webkit == true? 37+15: 32+15)
,"align":"center","sortable":false,"formatter":"actions",
"formatoptions":{"keys":true,"delbutton":false,"onSuccess":function (jqXHR) {actionresponse = jqXHR;return true;}
,"afterSave":function (rowID) {
cancelEditing($('#grid'));afterRowSave(rowID,actionresponse);actionresponse=null; }
,"onEdit":function (rowID) {
if (typeof (lastSelectedRow) !== 'undefined' && rowID !== lastSelectedRow)
cancelEditing($('#grid'));
lastSelectedRow = rowID;
}
}}
New row is added to jqgrid in loadcomplete event
var newRowData = {};
var newRowId = '_empty' + $.jgrid.randId();
$('#grid').jqGrid('addRowData', newRowId, newRowData);
and its id is updated if save action button is clicked:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}
After clicking save action button edit action button clicks are ignored. It is not possible to re-enter to edit mode after first editing.
How to fix this so that row can edited by edit button click again after saving ?
Update
I added $(this).focus() as suggested in Oleg answer and also wrapped id change into setTimeout as Oleg recommends in other great answer:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$(this).focus();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
setTimeout(function () {
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}, 50);
}
Problem persists. The problem may related to row id change since:
It occurs only in last row (where id is changed after save). It does not occur for saved rows where responseText returns same id and row id is actually not changed.
It does not occur if cancel action button is pressed.
Maybe row id needs additional reset id addition to resetSelection or needs updated in somewhere other place also.
Update2
I added code form updated answer to errorfunc and used only english characters and numbers id ids. This allows to click multiple times but introduces additional issue:
extraparam is no more passed. If rowactions() calls are commented out, extraparam is passed with with rowactions calls extraparam is not passed.
I changed jqGrid source code and added alert to rowactions method:
alert( cm.formatoptions);
if (!$.fmatter.isUndefined(cm.formatoptions)) {
op = $.extend(op, cm.formatoptions);
}
In first clicks alert outputs 'Object'. In succeeding clicks to Save button it outputs undefined. So for unknown reason formatoptions is cleared.
Remarks to comment:
Absolute url in testcase is not used. Datasource is set to localarray.
I verified that testcase works in IE and FF without external url access.
For extraparam issue I can create new testcase.
Without image directory buttons are shown in cursor is moved over them.
Missing image directory still allows to reproduce the issue.
FormData function is defined in js file.
Since new issue occurs after adding rowactions() calls and does not occur if those calls are removed, this seems to be related to the code proposed in answer.
I suppose that the problem exist because one hide a button which has currently focus. Look at the code from the answer. If one remove the line $(this).focus(); // set focus somewhere one has the same problem as you describes. So I suggest that you just try to set somewhere, for example in restoreActionsIcons the focus to any the table element of the grid after hiding the button having currently the focus. I can't test this, but I hope it will help.
UPDATED: I examined your problem one more time and I hope I can suggest you a solution.
You problem can be divided on two sub-problems. The main your problem is the the changing of the id of the row. So it is not common problem which everybody has.
The problem is that "actions" formatter create onclick functions directly in the HTML code (see for example here):
ocl = "onclick=$.fn.fmatter.rowactions('"+rowid+"','"+opts.gid+"','edit',"+opts.pos+");..."
So the functions will contains the original rowid. To fix the problem you can modify the code fragment of your aftersavefunc inside of setTimeout from
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
to something like the following:
var $tr = $("#" + rowID),
$divEdit = $tr.find("div.ui-inline-edit"),
$divDel = $tr.find("div.ui-inline-del"),
$divSave = $tr.find("div.ui-inline-save"),
$divCancel = $tr.find("div.ui-inline-cancel");
$tr.attr("id", json.Id);
if ($divEdit.length > 0) {
$divEdit[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','edit',0);
};
}
if ($divDel.length > 0) {
$divDel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','del',0);
};
}
if ($divSave.length > 0) {
$divSave[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','save',0);
};
}
if ($divCancel.length > 0) {
$divCancel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','cancel',0);
};
}
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
The second problem is that you use special characters inside of ids. I found a bug in the $.fn.fmatter.rowactions which need be fixed to support special characters in ids. The problem is that in the line 407 of jquery.fmatter.js the original rowid parameter rid will be changed:
rid = $.jgrid.jqID( rid )
and later everywhere will be used modified id. For example in the id is my.id the encoded version will be my\\.id. It's correct for the most places of the $.fn.fmatter.rowactions code (see here), but it' s incorrect as the rowid parameter of the editRow, saveRow, restoreRow, delGridRow, setSelection and editGridRow (see the lines 433-453). So the code must be fixed to use the original not escaped (not encoded) rid value with which the $.fn.fmatter.rowactions was called.
I think I will post tomorrow the corresponding bug report with the suggestions in the trirand forum.
UPDATED 2: The code $.fn.fmatter.rowactions(newId,'grid','edit',0); which I wrote above is just an example. I took it from the test demo which you send me. You should of course modify the code for your purpose. How you can see for example from the line the second parameter of the $.fn.fmatter.rowactions in the id of the grid which you use: 'grid', 'list' of something like myGrid[0].id. The last parameter should be the index of the column having formatter:'actions' in the colModel. You can use getColumnIndexByName function from the answer on your old question to get the index by column name.

Resources