I'm working on a small proof of concept. The goal is to produce a small javascript widget that clients would be able to drop into their site. This widget should detect all forms on the page (think name, email phone, etc) and post any submissions to our API before returning control to the form.
I've searched a bit to see if patterns or libraries exist for this and did not come up with many results (if anyone has some to share, thank you)
Considerations:
Won't know what other libraries are running on the site
Won't know if the page has 1 form or 100 forms
Won't know if the form submits with a simple action tag or something more complex
Do want to be as lightweight (vanilla) as possible
The approach that I've been working out so far does something like the following. However, a lot of forms tend to prevent the submit event for their own validation or method of submissions. Is there a better way to do this that would handle a wider set of use-cases?
window.onload = function() {
for(var i=0; i<document.forms.length; i++){
var form = document.forms[i];
form.addEventListener("submit", (e) => { // Hook, but not all forms will use this
e.preventDefault();
const formData = new FormData(form)
console.log(formData.entries()) // Submitted data
fetch('//some-api-url/', {
method: 'POST',
headers: {'Content-Type': 'application/json',},
body: JSON.stringify(formData.entries()),
}); // Send the data to our backend
return true; // Return control back to the original form
});
}
}
Related
Except the fact I am not able to use PHP. I have a single HTML file I can work with. So the only way is JS I think. And I have an "email" user input where the user sets his email and the n he is able to proceed, but I have to save his email first. Any ideas?
If you only need to save the element in a short term way you can use javascript and the HTML5 data element to save the email as an element of the current page. It is very temporary storage, but is the best you're going to get.
Edit:
Here's how you can do this using jQuery based javascript.
HTML:
<input type="text" id="email">
<input type="button" id="emailButton">
<div id="data_div"></div>
jQuery Javascript:
function retrieveEmail() {
var email = $('#data_div').data("email");
// do something with the email variable as needed here
// here's an example of retrieving it to send it to the server
var paramStr = "email=" + email;
$.ajax({
url: './your_server_file_here',
dataType: 'json',
data: paramStr,
success: function(data) {
callBack(data);
});
}
function callBack(data) {
// do something with information passed back from the server after you sent the data to the server (you didn't say you needed to do this, but here's where it should be done)
}
function storeEmail() {
var email = $('#email').val();
$('#data_div').data("email", email);
}
$(document).ready( function() {
$('#emailButton').click( function() {
storeEmail();
});
});
Edit: I know you already accepted this answer, but it struck me that HTML5 also includes another way to do this and it may provide the increase in power and flexibility that you're looking for. The HTML5 storage element can do pretty much the same thing as the data element except that it can persist and be accessed by other pages from the same domain either until the browser is closed (unlimited amount of data in the sessionStorage) or indefinitely (5mb of data in the localStorage). For implementation details and a greater understanding see here.
Be advised though, the HTML5 storage element is only available in HTML5 compatible browsers and should not be used if you fear your user base won't be using a modern browser. The HTML5 Data element will work even in older browsers, so it does have that advantage.
You could always use Javascript to create a text file where you can save information...
I've tried to search it through but not getting a starting point of how to approach AJAX in WordPress (or as a concept in whole), how is it different from jQuery, or is it a different/same module?
Why do we use it when we have jQuery (what circumstances forces us to use it?).
Should I learn jQuery basics first, then AJAX, or other way around?
You cannot really compare jQuery, AJAX and WordPress in this way:
jQuery is a JavaScript library designed to simplify the client-side scripting of HTML
AJAX is a technique to send data to, and retrieve data from, a server asynchronously
Wordpress is a blogging platform
To illustrate the point (with a very simple example), say you had a JavaScript event handler that was triggered when a form was submitted:
var f = document.getElementById("myForm");
f.onsubmit = doSomething;
You could have the event handler prevent the default submit action, instead making an AJAX request to a PHP script, optionally passing it some data (form values etc), then doing something with the response.
This has the advantage that the page is not refreshed, giving it a snappier, more responsive feel and generally making for a better user experience.
Here's how you'd implement it in plain JS:
var f = document.getElementById("myForm");
f.onsubmit = function(e){
e.preventDefault();
var r = new XMLHttpRequest();
r.open("POST", "submit.php", true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
console.log(r.responseText);
};
r.send("a=1&b=2&c=3");
}
Now, as mentioned, jQuery is a JavaScript library, that just adds a layer of syntactic sugar and smooths out browser incompatibilities.
The same code using jQuery:
var f = $("#myForm");
f.on("submit", function(e){
e.preventDefault();
$.ajax({
url: "submit.php",
type: "POST",
data: "a=1&b=2&c=3",
success: function(d) {
console.log(d);
}
});
});
ok, i'll try to better explain the question i am asking: I have an aspx webform that i am using to create an entity, simple data capture. This entity can have many child entities attached to it in a one to many relationship and that are created from the same form. I do not want to use a heavy asp.net component, like a datalist or any custom component to capture those. the way i am currently doing it is that i open a dialog in the page hosting a combobox populated with choices with an ajax call. once the user picks one of the entries and saves, i add an entry to a javascript collection that i use to keep the user choices and display them in a list on the client. when the user submits my form how can i submit this collection and reparse it on the server? I am thinking of using json to store,serialize and then deserialize. is this a good way?
You can post it using the following
var postData = function (myobjectinstance){
var objString = JSON.stringify(myobjectinstance);
$.ajax({
type: 'POST',
url: 'your url',
data: objString,
success: function (){
alert('did it');
},
dataType: 'json'
});
};
An then on the server with json.net you can deserialize the json string
// You can use JSON.Net
public static void PostMethod(string jsonstring)
{
var restoredObject = JsonConvert.DeserializeObject<MyObjectType>(jsonstring)
// do something with your object
}
Or you can use the PageMethods in combination with a scriptmanager if you are using a scriptmanager on your page. see this link for more info.
I am developing a web application and am using jQuery to provide a good user interface for users. Therefore, I am using ajax requests and many jQuery functions.
If I disable JavaScript in the browser most of the function will not work because I am sending asynchronous ajax requests for many functions. But how can I handle this? Do I need to rewrite the code without using jQuery and ajax?
Find a below a sample button click event:
$("#renameCategory").live('click', function (event) {
if ($.trim($("#CategoryNewName").val()) == "") {
alert("Please enter a category name");
return;
}
var selectedCategory = $("#SelectedCategoryId").val();
var newCategoryName = $("#CategoryNewName").val();
var postData = { categoryId: selectedCategory, name: newCategoryName };
$.ajax({
type: "POST",
url: '#Url.Action("UpdateCategoryName", "Category")',
data: postData,
dataType: "json",
success: function (data) {
$('#' + selectedCategory).text(newCategoryName);
$("#selectedCategoryText").html(newCategoryName);
},
error: function () { alert('error') }
});
});
How can I handle this?
Ajax requests and jQuery will not work when the client has JavaScript disabled. The best way to make this work is to use the URL from the <a> tag href like so:
Click Me!
$("#renameCategory").on('click', function (evt) {
//To prevent the link from sending the default request
//call preventDefault() on the jQuery event object
evt.preventDefault();
//
if ($.trim($("#CategoryNewName").val()) == "") {
alert("Please enter a category name");
return;
}
//GET THE URL FOR THE AJAX REQUEST
var actionUrl = $(this).attr('href');
//
var selectedCategory = $("#SelectedCategoryId").val();
var newCategoryName = $("#CategoryNewName").val();
var postData = { categoryId: selectedCategory, name: newCategoryName };
$.ajax({
type: "POST",
url: actionUrl,
data: postData,
dataType: "json",
success: function (data) {
$('#' + selectedCategory).text(newCategoryName);
$("#selectedCategoryText").html(newCategoryName);
},
error: function () { alert('error') }
});
});
You will also need to check for ajax requests in your Controller like below:
public ActionResult UpdateCategoryName() {
...
if(Request.IsAjaxRequest()) {
return Json(yourData);
}
return View();
}
This way, if your user has JavaScript disabled, the link will function like a normal HTTP request. If the user has JavaScript enabled, then they will get the Ajax experience. This is called graceful degradation.
Ajax call works when javascript is enabled.
You can handle it by server-side scripting, when javascript is disabled, you must do works by post/get requests, so you have to recode your web application.
If a lot of modification is needed for your website to work without javascript, then just force the users to enable javascript. One way to notify users to enable javascript is to use the noscript tag. http://www.w3schools.com/tags/tag_noscript.asp
View stackoverflow's page source to see how they use noscript
If JavaScript is disabled in the browser, the <script> tags won't be interpreted and executed in your document, including all your jQuery and AJAX JS code. The most common way to implement interactive web application other than Javascript is Flash, so you can still have a backup plan. You can also go with the old-school server side only generated dynamic pages.
Today, however it is very rare for someone not to have JavaScript enabled, so it should not be an issue at all.
Anyway you can make use of the <noscript> html tag to display a message to these users.
<script type="text/javascript">
... Js code ...
</script>
<noscript>You have JavaScript disabled in your browser. Please enable it.</noscript>
Obviously any functionality depending on script will not work if scripting is disabled, not available or incompatible with the environment it is trying to run in.
It is considered by many to be a good strategy to develop web applications so that they work without script support. You can then add scripting to improve the workflow and efficiency, but you will do so knowing that you have a fall back to a working system available if at any point the script should not run.
The discipline of designing and implementing a good workflow based on just HTML and forms may well lead to an easier interface to script and a more efficient workflow.
All too often developers throw together some minimal HTML and CSS, then try and do everything in script. The extreme is to have a DOCTYPE, title element, one block element and one script element that does everything. Not recommended.
I have three forms on a page. They each have multiple inputs including files. I would like so that when I submit the last form, the inputs for all three forms are sent to the POST data for the action location. I can jQuery if necessary.
Here's how you could combine multiple forms into one. Now, a warning: if you have more than one form with file-type inputs, you've got a problem that's really hard to solve. The browser will not let you use XMLHttpRequest (ie Ajax, in any form) to post a multi-part form POST with file inputs. You also won't be able to create a new form with the file inputs in it, because you can't set the value of file input elements with Javascript. Thus, the only way this can work is if you have multiple (3? whatever) forms, and only ONE Of them has file inputs. If that's the case, then what you can do is pull all the (non-file) inputs from the other 2 forms into the other form, and then submit that one.
function whenFormsCollide() {
// pass in one or more form elements
var forms = $.makeArray(arguments);
var hasFiles = 0, targetForm = null;
$.each(forms, function(i, f) {
if ($(f).find('input:file').length > 0) {
++hasFiles;
targetForm = f;
}
});
if (hasFiles > 1) throw "More than one form has 'file' inputs";
targetForm = targetForm || forms[0];
$.each(forms, function(i, f) {
if (f === targetForm) continue;
$(f).find('input, select, textarea')
.appendTo($(targetForm));
});
$(targetForm).submit();
}
I haven't tested that, but I've done stuff like it many times and I know that building up a <form> element works fine, even in IE6. (IE has some weird issues with form fields sometimes, but I think this part should be OK. At worst, instead of just being able to "move" the fields with that "appendTo" call you'd have to copy out the names and values and make new form fields.)
You may want to try using serialize() and append the string to your action URL.
You could submit them to hidden Iframes, that way you maintain control of the host page.
You can write one JS function that submits all three forms.
Your only option right now is a jQuery AJAX request (or a XMLHTTP one, but that's not recommended).
Try rethinking your design, I mean, why do you need 3 forms on one page... that's too `formy' for me already.
There is something else you can probably do: put the jQuery UI dialog box container div inside one form (this should work, I guess) and just have the fields within it...
I used below code to submit two forms' data in my website.
The idea is that you get the multiple forms data using serialize and combine that data and equalize that to data parameter of the $.ajax function.
.
// submits two forms simultaneously
function submit_forms(form1_id, form2_id)
{
var frm1_name = $("#" + form1_id).attr('name');
var frm2_name = $("#" + form2_id).attr('name');
if (frm1_name == frm2_name)
{
alert('The two forms can not have the same name !!');
}
else
{
var frm1_data = $("#" + form1_id).serialize();
var frm2_data = $("#" + form2_id).serialize();
if (frm1_data && frm2_data)
{
$("#div_busy").html('<strong>Processing...</strong><br /><img id="busy" src="./images/progress_bar.gif" border="0" style="display:none;" />');
$("#busy").fadeIn('slow');
$.ajax(
{
type: "POST",
url: "process_sticker_request.php",
data: frm1_data + "&" + frm2_data,
cache: false,
error: function()
{
$("#busy").hide('slow');
$("#div_busy").css({'color':'#ff0000', 'font-weight':'bold'});
$("#div_busy").html('Request Error!!');
},
success: function(response)
{
$("#div_busy").hide('slow');
$("#hdnFormsData").html(response);
// open popup now with retrieved data
window.open('', 'popup2', 'toolbars = 1, resizable=1, scrollbars=1, menubar=1');
document.getElementById("prt").action = 'win_sticker.php';
document.getElementById("prt").target = 'popup2';
document.getElementById("prt").submit();
// reset the action of the form
document.getElementById("prt").action = 'list_preview.php';
}
});
}
else
{
alert('Could not submit the forms !!');
}
}
}
Can you explain the sense of separating information in different forms and combine the information later with JS? And when Java Script is disabled your Formulas didn't work?
Put all together in one form. If you want to evaluate only the special data Fields of your Form, check on the server side which submit button was pressed.
When you have a problem an you need JS to fix a normal communication problem, then you have a conceptional problem. JS can help you to customize and give a better UI - but this problem is useless.