AJAX created SELECT "invisible" inside FORM data - ajax

I'm new here but I found many help in the passt reading Q&A.
My problem is this:
in a HTML page I have a form with many fields, one of these is a SELECT with name and id "f_container"; I pose it inside a element (<div id=f_cont_ins></div>) ad use an AJAX function to populate it dynamically.
function ele_con(id,cod_cont) {
var http = createRequestObject();
http.open('get', 'fler.php?id='+id+'&art='+document.getElementById('stp').value);
http.onreadystatechange = function() {
if(http.readyState == 4){
var response = http.responseText;
document.getElementById('f_cont_ins').innerHTML = response;
}
}
http.send(null);
}
The "response" is right formatted an display right in the browser (Firefox); if I inspect the element or analyze the DOM structure it seems all ok, and I can get the value of a selection with document.getElementById('f_container').value.
But when I post the form, the field "f_cointainer" isn't present in the print_r($_POST); array, but all the other yes.
I navigate the net but don't found a clear ansver that these is not possible or a workaround to solve the problem.
I have an idea that is to use the document.location='page.php?par1=a&par2=b&f_container=5'; created reading value with document.getElementById, but I prefer a POST solution if it exist.

Related

GravityView Ajax Link

I have a table created with GravityView and I want to implement the single entry link with Ajax so that the page does not refresh and the URL does not change.
Is such a thing possible?
enter image description here
You can load the single entry page with jQuery .load method.
You would need to pass the URL of the page, in this case I am trying to get the content on another page whose URL is in the anchor link of the table, in your case its link field.
So i give the .load method URL + the id of the accordion in which the content i need to display exists, and a call back function.
Here how I did it.
jQuery( document ).ready(function($) {
// select the div where you want to display content
var $loadedContent = $('#fl-accordion-5c450fd66133e-panel-0');
// register an event, get the click event of the link
$(document).on('click','.gv-field-3-date_created a', function(event) {
//stop the link form opening
event.preventDefault();
//get URL from the href attribute of the anchor link
var $url = $(this).attr("href");
// send the request and get the response, In my case I am trying to show the content inside a accordian, so i have taken its ID and added that with URL
$loadedContent.load($url+' #fl-accordion-5c450fd66133e-panel-0', completeFunction);
return false;
});
function completeFunction(responseText, textStatus, request) {
if(textStatus == 'error') {
// show a relevant message
$loadedContent.text('An error occurred during your request: ' + request.status + ' ' + request.statusText);
}
}
});
Just add your classes, and it will get the Job Done.
Thanks for using GravityView! Zack here, founder.
We’re going to be adding this functionality later this year. If you wait a few months, it’ll be ready!

Filling MVC DropdownList with AJAX source and bind selected value

I have view for showing Member details. Inside there is an EditorFor element which represents subjects taken by the member.
#Html.EditorFor(m => m.Subject)
Inside the editor template there is a Html.DropDownListFor() which shows the selected subject and button to delete that subject
I am using an Html.DropDownListFor element as :
#Html.DropDownListFor(m => m.SubjectID, Enumerable.Empty<SelectListItem>(), "Select Subject",
new { #class = "form-control subjects" })
The second parameter(source) is set empty since I want to load the source from an AJAX request; like below:
$.getJSON(url, function (response) {
$.each(response.Subjects, function (index, item) {
$('.subjects').append($('<option></option>').text(item.Text).val(item.ID));
});
// code to fill other dropdowns
});
Currently the html loads before the dropdowns are filled. So the values of all subject dropdowns are set to the default "Select Subject". Is there a way around this or is it the wrong approach?
Note: There are a number of dropdowns in this page. That's why I would prefer to load them an AJAX request and cache it instead of putting in viewModel and filling it for each request.
** EDIT **
In AJAX call, the action returns a json object containing dropdowns used across all pages. This action is decorated with [Output Cache] to avoid frequent trips to server. Changed the code in $.each to reflect this.
You can initially assign the value of the property to a javascript variable, and use that to set the value of the selected option in the ajax callback after the options have been appended.
// Store initial value
var selectedId = #Html.Raw(Json.Encode(Model.Subject.SubjectID))
var subjects = $('.subjects'); // cache it
$.getJSON(url, function (response) {
$.each(response, function (index, item) {
subjects.append($('<option></option>').text(item.Text).val(item.ID));
});
// Set selected option
subjects.val(selectedId);
});
However its not clear why you are making an ajax call, unless you are generating cascading dropdownlists which does not appear to be the case. What you doing is basically saying to the client - here is some data, but I forgot to send what you need, so waste some more time and resources establishing another connection to get the rest of the data. And you are not caching anything despite what you think.
If on the other hand your Subject property is actually a collection of objects (in which case, it should be Subjects - plural), then the correct approach using an EditorTemplate is explained in Option 1 of this answer.
Note also if Subject is a collection, then the var selectedId = .. code above would need to be modified to generate an array of the SubjectID values, for example
var selectedIds = #Html.Raw(Json.Encode(Model.Subject.Select(x => x.SubjectID)))
and then the each dropdownlist value will need to be set in a loop
$.each(subjects, function(index, item) {
$(this).val(selectedIds[index]);
});
If your JSON tells you what option they have selected you can simply do the following after you have populated your dropdown:
$('.form-control.subjects').get(0).selectedIndex = [SELECTED_INDEX];
Where [SELECTED_INDEX] is the index of the element you want to select inside the dropdown.

Issue submitting wysiwyg data through Ajax

I am Using Cl Editor On a Cms in a working on, Everytime i submit data through ajax i am having problems with it.
Let's say i write 10 lines in my wysiwyg editor but i only receive 3 or 4 in php, after some debugging in firebug what i have noticed is the html i am sending through ajax contains a span with class "Apple-converted-space" <span class="Apple-converted-space"> </span> i am able to get everything before this span, but the text after this span is missing. I have no idea what it is. Let me write my code for better understanding.
To get cleditor data
var data = $(".cleditorMain iframe").contents().find('body').html();
Ajax Form Submission
if(window.XMLHttpRequest)
{
xmlhttp = new window.XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == '4' && xmlhttp.status == '200')
{
}
}
parameters = 'data=' + data
xmlhttp.open('POST', 'libs/make_procedure.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send(parameters);
return true;
I have also tried jquery ajax method.. same problem exists there, so please do not ask me to use the other way to submit data via ajax.
Thanks
You may want to check whether it is javascript that is not sending correct data or your backend that is not able to receive it.
So first you should debug in javascript by writing an alert(data); statement right after you get the data from that cieditor control, and see what do you get there. Use Firefox and you can also copy the html using mouse pointer from the alert box. (which is not possible in IE)
You should also check the cieditor specs to see if there is any easier way to get data in javascript.
You may also want to consider using CKEditor.
You are posting the data without escaping the contents of the data. Since the & is the seperator for different fields in a post, data will contain only the part up untill the first &. Use encodeURIComponent to escape the data value.
Change the line
parameters = 'data=' + data
to
parameters = 'data=' + encodeURIComponent(data);
See also: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent

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

How to change WebGrid action for getting data (.NET MVC3)

I have a Partial View that renders WebGrid. My controller looks like
public ActionResult Index()
{
return View();
}
public ActionResult GetUserList(int? page, string sort, string sortdir)
{
var model = UserModel.getList(page,sort,sortdir);
return PartialView("_UserList",model);
}
Index.cshtml :
....
#Html.Action("GetUserList")
The problem is that every time I click on grid navigation or sort links it calls Index method. How can I make Webgrid to execute a different action (GetUserList in this case)? I'm sure I can prepend GetUserList to all links in grid using jquery, but I believe it should be a better way.
It's also possible that what I'm doing is completely wrong, so thanks for your suggestions.
After lot of monkeying around and digging (and even fiddling with Reflector with WebGrid's source code), I came to the conclusion that with WebGrid, you cannot control/change the Header link action.
To create the header link URL, the path is taken from HttpContext.Request.Path, so there is no way to customize it to point to a different route.
One very ugly hack would be to tap into to jQuery Ajax's events (since the header link uses jQuery.load to sort) and overwrite the URL:
Album Id
Better solution would be to use:
Telerik Grid which lets you specify custom routes and also offers much more flexibility in rendering your layout
or MvcContrib Grid (not sure if this lets you modify header links but definitely offers more flexibility than WebGrid)
#MrChief had the idea above about the ugly hack...I put that together. Here is the main code that I used to do this. It does, indeed, hijack the ajax call before it is put on the wire. The key is to modify the URL that is getting sent because the grid will grab that URL from HttpContext.Request.Path. and plug it into the onclick for the anchor element.
I put this into my main common.js and will simply attach a function to capture the ajaxSend event which happens just before the data is sent.
// Used to hijack the sending of all AJAX calls. Before it sends the call to the server, it checks to see if the
// active element (the element that prompted the call) is marked with a given class. If so, then it will perform
// the given operation.
$(document).ajaxSend(function (event, jqXHR, ajaxOptions) {
var activeElement = document.activeElement;
if ($(activeElement).attr('redosorturl') != null) {
// If this is a sort anchor link from a grid that needs to have the sort link redone, do it here.
// the code is in the eipGrip.js file.
if ($(activeElement).attr('redosorturl').toString() == 'redoSortURL') {
var newURL = RedoGridSortURL(activeElement, ajaxOptions.url.toString());
ajaxOptions.url = newURL.toString();
}
}
return false;
});
When rendering the page, I have marked the tag in column header that contains the incorrect URL with a class named "redosorturl', so I know when I hijack the ajax call, the operation has to be done on this element. I then call a custom function that gives me the correct URL, then the ajaxOptions.url is then rewritten with that new URL.
I have to pass the activeElement to that rewrite function so I can traverse up the DOM to get the grid information, where I have put data like the controller and action method that is used along with and IDs and other info that I use for the URL. Likewise, I pass in the current url string because the grid will inject a token at the end of the url that I parse off and put on the new url.
Your conclusion isn't right. You just need to wrap your webgrid in a Get form:
using (Html.BeginForm("GetUserList", "ThingaMaBob", System.Web.Mvc.FormMethod.Get))
{
var grid = new WebGrid(
...
));
Html.Hidden(grid.SortFieldName, grid.SortColumn);
Html.Hidden(grid.SortDirectionFieldName, grid.SortDirection == SortDirection.Ascending ? "ASC" : "DESC");
}
The hiddens are so that the sort dir and sort field end up in parseable form in the querystring. You end up with urls like localhost/ThingaMaBob/GetUserList?someotherfields=whatever=&sort=city&sortdir=ASC
If you remove [HttpPost] attribute and let the route come to the same function. you'll find the Request["page"] value in your method. this will allow you to put a check on Request["Page"] value.

Resources