jQuery .clone() Entire HTML Form AND All Its Values - javascript

I'm using jQuery and an $.ajax() call to post some complex HTML via POST to my database. I'm able to get the form's structure via .html(), but the user's selections are lost in the process. I thought I could use .clone() instead but I got this error:
Uncaught InvalidStateError: Failed to read the 'selectionDirection'
property from 'HTMLInputElement': The input element's type ('hidden')
does not support selection.
// Cloning my form
var myFormHTML = $("#myForm").clone();
console.log(myFormHTML);
var inputData = {
advancedSearchHTML: myFormHTML,
otherParam: otherVar
};
console.log(inputData);
// JS ERROR is down here in the $.ajax() call:
$.ajax({
type: "POST",
url: 'serverSideScript.php',
dataType: 'html',
data: inputData,
success: function (response) {
console.log(response);
}
});
These forms are very complex and they include over 100 <input type="hidden">'s which change according to the user's selections. I can't change the way this works. So my problem is that I have complex forms with HTML generated by the user and I need to copy both the HTML AND all its values so that it can be inserted into my database and eventually reloaded back into the DOM, perhaps months later. Any ideas?
EDIT: I've tried everything I can think of but I can't seem to get user input values out of the HTML, which is frustrating because I'm used to just hitting "Copy HTML" in Chrome's Inspector, so to me it seems like it should be easy to get that same HTML out of the <form> as a string. Some of the things I've tried:
$myFormHTML.html()
$myFormHTML.innerHTML
$myFormHTML.outerHTML
$myFormHTML.get(0).innerHTML
$myFormHTML.get(0).outerHTML
JSON.stringify($myFormHTML.html())
I've got it down to the point where I've got a complete jQuery Object which, when appended to the DOM, has all the user's input included (:selected states, :checked states, input values, etc.). I need to take this jQuery Object and spit out all its HTML content into a string that can be transferred to the server. Does anyone have any idea what to do? Maybe there's a way to do the same loop that gets done during an $.append() so I could build up a string from scratch? Any other ideas?

http://api.jquery.com/serialize/
This does exactly what you want, except since your form is built by user-input you cannot verify if it's a valid form or not. If the form markup is incorrect, you cannot serialize the data.
Here is the example:
http://jsfiddle.net/jyc30nxz/1/
$('#myForm').serialize();
An important aspect of this is if your form inputs do not have the "name" attribute, then you cannot return it's value during serialization which is why you end up with an empty string.
Edit:
This also works:
console.log($(this).clone().html())
My guess is your form markup is invalid

Have you tried to .serialize the form contents?

Related

Ajax scraping: getElementByTagName as plaintext

I have a URL that I'd like to scrape a certain bit of information from and I'd preferably do that by obtaining the element. I'd also need to get it as plaintext, but I'm still pretty new to Ajax/jQuery and don't quite know what the correct syntax is..
My ajax call is:
$.ajax({
url: URL,
dataType: 'text',
success: function(data) {
var info = data; //How can I get a table from the data without loading the whole site extracting a small portion?
if(info != undefined) {
console.log(info); //Needs to be plaintext.
}
}
});
I hope my question is clear... I'm essentially loading a website and retrieving a table or class name as plaintext... How could I do that? Thanks.
Your options on the client-side are:
1.) First, optionally use a regular expression to isolate that tag contents, but this is usually considered rather costly.
2.) Create a node, then drop the text into it's innerHTML.
That's usually the standard way of rendering text responses to the DOM.
Neither one are all that lightweight.
If you just need to pick something out of the text, use Regular Expression. Also, as mentioned, be aware of XSS and cross-origin policy.
Additionally, you may want to handle this on the server-side.

jQuery alters page - but how/where do I "acquire" the changes?

This post by #BenjaminRH (How to change/edit the text of a paragraph/div using jQuery?) provides exactly the sort of functionality I'm trying to build on.
By clicking on a button, a new paragraph is created on the page, which can be edited and saved to the page.
I want to save it to a database. When I look at the page source after editing, I don't see the changes there, which doesn't surprise me... but I don't know where to "capture" the changed text so that I can validate and post to mySQL.
JQuery is a javascript library - which runs client side. If you wanted to save that data into the database - you would have to send it to the server (php/asp/mvc etc) using ajax and then insert the data into the database.
See the jquery Ajax function for details on how to accomplish sending data asynchronously.
Create the data in javascript that you want to show and save in database.
Wrap the data in JSON and use ajax to POST the data to the server side code
Server-side retrieve the posted data and parse it into something usable
Server-side write a script to insert the data into the database.
Handle any errors that may occur.
Pseudo-code:
// step 1
var someData = 'this is my data';
$("#myDiv").html(someData);
// step 2
$.ajax({
type: "POST",
dataType: 'json', // <-- if the data is complex and needs to be object-oriented
url: "some.php", // <-- that is the file that will handle the post server-side.
data: JSON.stringify({ someData }) // <-- just pass someData if your data is not complex
})
.always(function(jqXHR, textStatus) {
if (textStatus != "success") {
// step 5: handle error.
alert("Error: " + jqXHR.statusText); //error is always called .statusText
} else {
alert("Success: " + jqXHR.response); //might not always be named .response
}});
OK, I've managed to solve it for myself, without using ajax. I took the example from (How to change/edit the text of a paragraph/div using jQuery?) and modified it by placing the elements in an (html) form.
The second modification was to use <textarea> elements, not <p> elements, as <p> elements cannot be posted.
As #caspian pointed out (in the comments) those two steps do populate the $_POST array and away we go.

Alpaca.js checkbox renderedForm.getValue() serialization issue

Below is a function which is called in my alpaca "postRender" callback :
function onClickDefaultParameterButtons(renderedForm) {
$('#paramFormSaveBtn')
.click(
function() {
if (renderedForm.isValid(true)) {
val = renderedForm.getValue();
paramIdDefaultMap[curParameterIdSelect].Parameter.Value = JSON
.stringify(val);
genericJsonAjaxCall(
"${RestUrlBase}/DefaultParameters/"
+ curParameterIdSelect,
"put",
JSON.stringify(paramIdDefaultMap[curParameterIdSelect]),
saveDefaultParameterChangesSuccessCallback,
false);
}
});
}
I have a checkbox in this form and it has some issues with serialization.
For example, if the checkbox is checked, it will show up as a value in the renderedForm.getValue() return.
If the checkbox is not checked, it will not show up as a value in the renderedForm.getValue() return.
Another issue I found is when I have a number field and put the value of 0, it also does not show up in the renderedForm.getValue(). I need all form values to show up whether they are checked, not checked or even 0.
Is there a way to get around this?
Others have said that POST/GET behaviour of the browser is to blame, but that's not the case for raw JSON serialization. You should be able to serialize your data and POST the raw JSON result to some service without a problem. The way a browser encodes form elements is not relevant to that.
The problem is in the alpaca's serialization code itself, where fields are only added if their value would pass this statement:
if (assignedValue)
{
o[propertyId] = assignedValue;
}
So, if assignedValue is 0, or false, it won't be serialized. This is different than expected behaviour, which I think makes it a bug.
I have forked the alpaca code to handle this serialization as you (and I) would expect. A pull request is pending. Feel free to use it as is:
https://github.com/tylerperyea/alpaca
Or just change this contents of the js/fields/basic/ObjectField.js file, and rebuild.
You may also comment on the issue:
https://github.com/gitana/alpaca/issues/158

Change value of dynamic inputs

I have a modal window that has a lot of new dynamic elements (inputs, buttons, etc.). I want to see if a certain element(or in this case, and input) gets created and if it does, then change its value.
The scenario is that if I make an ajax request for populating data, and as the user browses the modal window I can reuse some of that data. When the input field I'm looking for gets created, I can just put the value of the ajax call I made previously.
I have tried: $("#myinput_id").val(sellerData['id']);
obviously the above wont work because the element doesn't exists, yet. I'm also trying to avoid new ajax calls for the same data :/
Any thoughts?
$( "#add").bind('click', function() {
$.ajax({
url: '/seller/get',
type: 'POST',
success: function(response) {
sellerData = jQuery.parseJSON(response);
//other code here
//this doesn't work
$("#myinput_id").val(sellerData['id']);
}
});
});
Then the above gets triggers. The input field doesn't exist yet. How can I make it "look for it" if in the future the input field gets created?
Try using .length http://api.jquery.com/length/
if($("#myinput_id").length) //There is at least one element selected
//Do something
a bit confusing question you are saying u want to populate the data and your are using POST

Any function with mixed functionality of .ajax() and .load()?

.ajax() can send a post request and get data in return where as .load() can get any element in the rendered page. How to create a form when submitted(asynchromously) instead of getting back some data should get the page element of the rendered page that would be generated had there been normal submission instead of ajax submission?
I dont want to write views(Django) for xhr, normal requests separately. So, When I submit a form by ajax I dont want to hijack default action but only want to get some element of the rendered post submission page instead of actually being redirected to that post submission page which would have happened hadn't it been an xhr request.
Update:
load will do a POST rather than a GET if you supply the data to send as an object rather than a string. From the docs:
Request Method
The POST method is used if data is provided as an object; otherwise, GET is assumed.
So:
$("#target").load("/path/to/resource selector_for_relevant_elements", {});
..should convert the load from GET to POST. Of course, you'd replace {} with the arguments you want to send.
Original answer:
You can do the POST directly with ajax and then process the returned HTML yourself. For instance, to turn this load:
$("#target").load("/path/to/resource selector_for_relevant_elements");
..into a POST:
$.ajax({
url: "/path/to/resource",
method: "POST",
dataType: "html",
success: function(html) {
// Build the elemnts of the result in a disconnected document
var page = $("<div>").append(html); // See note below
// Find the relevant elements and put them in target
$("#target").html(page.find("selector_for_relevant_elements"));
}
});
I've done the wrapper div because that's what jQuery's load function does. You may want to look at the source for load (that line number will rot, of course, but the filename is unlikely to change) to see if there are other tricks you need to replicate.

Categories

Resources