javascript not working form.textid.indexOf("") - indexof

I have this code and it worked for a few minutes. However I reloaded my page and now I cannot get it to work and I cannot figure out why. Any help would be much appreciated.
Code:
<form>
<input type="text" id="test">
<input type="button" value="test" onclick="check(this.form)">
<script lang="JavaScript">
function check(form) {
if (form.test.indexOf("yes")) {
alert("play sound");
}
else {
alert("no sound");
}
}
</script>
</form>

When I tested your code in Google Chrome's Javascript console, I got Typeerror: cannot read property 'test' of undefined. It looks like you're trying to validate the user input in the input box, but whatever value entered needs to be referenced in your code before finding the string segment of that string with the indexOf ().
Here's a jsFiddle of showing you how to get the user input value with jQuery.
Use jQuery's val() method or Javascript's value() method to get the user input, then you can use indexOf method to find the string segments
var arr=["random","Javascript","donuts","closures"];
$(document).ready(function() {
$("#myForm").submit(function(e){
e.preventDefault();
var userInput=$("#userInput").val();
if($.inArray(userInput,arr) != -1){
alert("success");
}
})
});

Related

AJAX shows different behaviors in an if/elseif-statement which is inside the success function [duplicate]

I have looked through all the similar posts out there but nothing seems to help. This is what I have
HTML:
<section>
<form id="contact-form" action="" method="post">
<fieldset>
<input id="name" name="name" placeholder="Name" type="text" />
<input id="email" name="email" placeholder="Email" type="text" />
<textarea id="comments" name="comments" placeholder="Message"></textarea>
<div class="12u">
Send Message
Clear Form
</div>
<ul id="response"></ul>
</fieldset>
</form>
</section>
JavaScript/jQuery:
function sendForm() {
var name = $('input#name').val();
var email = $('input#email').val();
var comments = $('textarea#comments').val();
var formData = 'name=' + name + '&email=' + email + '&comments=' + comments;
$.ajax({
type: 'post',
url: 'js/sendEmail.php',
data: formData,
success: function(results) {
$('ul#response').html(results);
}
}); // end ajax
}
What I am unable to do is prevent the page refresh when the #form-button-submit is pressed. I tried return false; I tried preventDefault() and every combination including return false; inside the onClick. I also tried using input type="button" and type="submit" instead and same result. I can't solve this and it is driving be nuts. If at all possible I would rather use the hyperlink due to some design things.
I would really appreciate your help on this.
Modify the function like this:
function sendForm(e){
e.preventDefault();
}
And as comment mentions, pass the event:
onclick = sendForm(event);
Update 2:
$('#form-button-submit').on('click', function(e){
e.preventDefault();
var name = $('input#name').val(),
email = $('input#email').val(),
comments = $('textarea#comments').val(),
formData = 'name=' + name + '&email=' + email + '&comments=' + comments;
$.ajax({
type: 'post',
url: 'js/sendEmail.php',
data: formData,
success: function(results) {
$('ul#response').html(results);
}
});
});
function sendForm(){
// all your code
return false;
}
I was also bit engaged in finding solution to this problem, and so far the best working method I found was this-
Try using XHR to send request to any url, instead of $.ajax()...I know it sounds bit weird but try it out!
Example-
<form method="POST" enctype="multipart/form-data" id="test-form">
var testForm = document.getElementById('test-form');
testForm.onsubmit = function(event) {
event.preventDefault();
var request = new XMLHttpRequest();
// POST to any url
request.open('POST', some_url, false);
var formData = new FormData(document.getElementById('test-form'));
request.send(formData);
This would send your data successfully ...without page reload.
Have you tried using
function sendForm(event){
event.preventDefault();
}
Simple and Complete working code
<script>
$(document).ready(function() {
$("#contact-form").submit(function() {
$("#loading").show().fadeIn('slow');
$("#response").hide().fadeOut('slow');
var frm = $('#contact-form');
$.ajax({
type: frm.attr('method'),
url: 'url.php',
data: frm.serialize(),
success: function (data) {
$('#response').html(data);
$("#loading").hide().fadeOut('slow');
$("#response").slideDown();
}, error: function(jqXHR, textStatus, errorThrown){
console.log(" The following error occured: "+ textStatus, errorThrown );
} });
return false;
});
});
</script>
#loading could be an image or something to be shown when the form is processing, to use the code simply create a form with ID contact-form
Another way to avoid the form from being submitted is to place the button outside of the form. I had existing code that was working and created a new page based on the working code and wrote the html like this:
<form id="getPatientsForm">
Enter URL for patient server
<br/><br/>
<input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
<input name="patientRootUrl" size="100"></input>
<br/><br/>
<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
</form>
This form cause the undesirable redirect described above. Changing the html to what is shown below fixed the problem.
<form id="getPatientsForm">
Enter URL for patient server
<br/><br/>
<input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
<input name="patientRootUrl" size="100"></input>
<br/><br/>
</form>
<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
I expect anyone to understand my idea very well as it's a very simple idea.
give your required form itself an id or you can get it by any other way you prefer.
in the form input "submit" call an onclick method from your javascript file.
in this method make a variable refer to your from id the addEventListener on it and make a preventDefault method on "submit" not on "click".
To clarify that see this:
// element refers to the form DOM after you got it in a variable called element for example:
element.addEventListener('submit', (e) => {
e.preventDefault();
// rest of your code goes here
});
The idea in brief is to deal with the form by submit event after dealing with submit button by click event.
Whatever is your needs inside this method, it will work now without refresh :)
Just be sure to deal with ajax in the right way and you will be done.
Of course it will work only with forms.
The way I approached this: I removed the entire form tag and placed all the form elements such as input, textarea tags inside a div and used one button to call a javascript function. Like this:
<div id="myform">
<textarea name="textarea" class="form-control">Hello World</textarea>
<button type="submit" class="btn btn-primary"
onclick="javascript:sendRequest()">Save
changes</button>
<div>
Javascript:
function sendRequest() {
$.ajax({
type: "POST",
url: "/some/url/edit/",
data: {
data: $("#myform textarea").val()
},
success: function (data, status, jqXHR) {
console.log(data);
if (data == 'success') {
$(`#mymodal`).modal('hide');
}
}
});
return true;
}
I thought why use a form when we are sending the actual request using AJAX. This approach may need extra effort to do things like resetting the form elements but it works for me.
Note:
The above answers are more elegant than this but my use case was a little different. My webpage had many forms and I didn't think registering event listeners to every submit button was a good way to go. So, I made each submit button call the sendRequest() function.

Spring mvc Ajax search Form with Thymeleaf

I'm trying to add a search form in the navbar on every page in my spring mvc web app, just like the one here on stackoverflow, and I'm having issues. Right now I have a working search functions on a couple of my pages, using the typical mvc forms. I take the inputted string and store a variable called "searchString" in an object I created called "searchForm.java". Then I try to query that inputted string in the database using spring data's findbycontaing method, and then put that result on the model, and then represent that on the view, using thymeleaf. However I think that the navbar should be done using ajax, since it's on every page and pages with other forms.
So I think I'm sending the string that was submitted to the search form in the navbar to the controller where I queried it in the repository to bring back search results, then I tried to put the search results on the model, but I get nothing, all it does is redirect me to the search page. I may not be making very much sense, but I'll show my code, and if anyone could let me know if I'm going about my problem in the right way or not, and if you guys see any errors in my code. Thanks in advance.
So here's my ajax and jquery to submit the form.
<script th:inline="javascript">
/*<![CDATA[*/
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$(document).ready(function(){
$("#searchButton").on("click", function(ev) {
$.ajax({
url : "navSearch",
type : "post",
data : {
"newSearch" : $("#newSearch").val()
},
success : function(data) {
console.log(data);
},
error : function() {
console.log("There was an error");
}
});
});
});
/*]]>*/
</script>
There may be an issue here, because in the console in the chrome developer tools, before it redirects, a message pops up very quickly that says uncaught TypeError: Cannot read property 'toLowerCase' of undefined, and it's coming from jquery.min.js:5 so that could be my issue, but I have no idea how to go about fixing this, and I've searched for answers so far with no luck.
Here's my html form, I think this shouldn't be a problem, but who knows, so I'll put it up anyways. And I'm using thymeleaf for this view.
<form action = "setSearch" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" id="newSearch"></input>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
</div>
<button type="submit" class="btn btn-default" id="searchButton">Search</button>
</form>
Here's my searchForm.java class, where I temporarily store the string to be queried in the database.
public class SearchForm {
private String searchString;
public String getSearchString()
{
return searchString;
}
public void setSearchString(String searchString)
{
this.searchString = searchString;
}
}
And Here's my controller, where I'm trying to handle the ajax submission and return it as search results on the setSearch.html page. What I'm thinking here is that the string "newSearch" from the form could be matched using the Spring Data query methods, and then be able to return it and add it to the model, but it's not working, it's just redirecting me to the /searchSet page with no data, because that's where the form action goes and that's what I tell it to return. So honestly I'm no sure if any data is even getting to this point.
#RequestMapping(value="setSearch/navSearch", method=RequestMethod.POST)
public #ResponseBody String navSearch (#RequestParam String newSearch, ModelMap model)
{
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
And here's an example of a working search method that I have in my controller that I use on a regular form, with no ajax, on the /searchSet page.
#RequestMapping(value="/setSearch", method=RequestMethod.GET)
public String searchGet(ModelMap model) {
SearchForm searchForm = new SearchForm();
model.put("searchForm", searchForm);
return "setSearch";
}
#RequestMapping(value="/setSearch", method=RequestMethod.POST)
public String searchPost(#ModelAttribute SearchForm searchForm, ModelMap model) {
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(searchForm.getSearchString());
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
UPDATE
I've changed my code in the form from <button type="submit" class="btn btn-default" id="searchButton">Search</button> to <button type="button" class="btn btn-default" id="searchButton">Search</button> and now I get the Uncaught TypeError: Cannot read property 'toLowerCase' of undefined from earlier and nothing happens with the page.
UPDATE
I can now submit the ajax form without a problem, I was missing meta tags in the header, so the csrf wasn't submitting correctly, so now I get this error in the chrome developer tools console XHR Loaded (navSearch - 405 Method Not Allowed - 7.265999971423298ms - 634B)
UPDATE
Now everything works on the Ajax side, I needed to adjust my url to match the url I had in the request mapping on the controller and it runs through all the code fine. However the overall search function still doesn't work, here's my updated controller.
I know my issue here is that I'm returning a string and not an object, but I'm not sure how to return the object and then redirect the url to the /setSearch page. It's running through the code and returning a string "setSearch" in the console, because I told it to at the end of the controller.
#RequestMapping(value="/setSearch/search", method=RequestMethod.POST)
public #ResponseBody String search (#RequestParam String newSearch, ModelMap model)
{
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
Here's my working ajax
<script th:inline="javascript">
/*<![CDATA[*/
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$(document).ready(function(){
$("#searchButton").on("click", function(ev) {
$.ajax({
url : "/setSearch/search",
type : "post",
data : {
"newSearch" : $("#newSearch").val()
},
success : function(data) {
console.log(data);
},
error : function() {
console.log("There was an error");
}
});
});
});
/*]]>*/
</script>
but it's not working, it's just redirecting me to the /searchSet page
with no data, because that's where the form action goes and that's
what I tell it to return
You are right, it is because you are submitting the form and in the action you specify it to submit to setSearch, that is why the page is getting redirected to the same page. Just replace button type="submit" with button type="button" so that the form will not be submitted when searchButton is clicked.

Blur() event doesn't work for me

This is my jQuery code:
$('input[name="Search"]').blur(function(e) {
$(this).text('');
});
And my HTML snippet:
<input name="Search" type="text" id="Search" class="MainMenu" />
But it doesn't work, does anybody know why?
try .val() insteadof .text()
$('input[name="Search"]').blur(function(e) {
$(this).val('');
});​
You are using text() on input type text which is not defined for input type=text. You need to use val()
Live Demo
$('input[name="Search"]').blur(function(e) {
$(this).val('');
});​
If you have id, you can use id as it will be more efficient then getting element with name selector.
Live Demo
$('#Search').blur(function(e) {
$(this).val('');
});​
there is no method like .text() for input type text use .val()
these change will help you
$('input[name="Search"]').blur(function(e) {
$(this).val('');
});
or
$('#Search').blur(function(e) {
$(this).val('');
});​
Documentation here

Liftweb: create a form that can be submitted both traditionally and with AJAX

Is it possible in Lift web framework to create forms (and links) that react via AJAX, but also work without Javascript support? If so, how?
When I build the form using <lift:form.ajax>, the form's action is set to javascript:// so that it no longer submits without JS. If I build the form without explicit AJAX support, I don't know how to insert the AJAX functionality.
I suppose I could build a RESTful interface (we'll have to build that anyway) and write custom Javascript to submit the form through that. I would like to avoid code duplication, though: if it is possible to handle all three inputs (RESTful, traditional HTTP POST, AJAX) with the same code, that would be best.
Take a look at http://demo.liftweb.net/form_ajax
FormWithAjax.scala
class FormWithAjax extends StatefulSnippet {
private var firstName = ""
private var lastName = ""
private val from = S.referer openOr "/"
def dispatch = {
case _ => render _
}
def render(xhtml: NodeSeq): NodeSeq =
{
def validate() {
(firstName.length, lastName.length) match {
case (f, n) if f < 2 && n < 2 => S.error("First and last names too short")
case (f, _) if f < 2 => S.error("First name too short")
case (_, n) if n < 2 => S.error("Last name too short")
case _ => S.notice("Thanks!"); S.redirectTo(from)
}
}
bind( "form", xhtml,
"first" -> textAjaxTest(firstName, s => firstName = s, s => {S.notice("First name "+s); Noop}),
"last" -> textAjaxTest(lastName, s => lastName = s, s => {S.notice("Last name "+s); Noop}),
"submit" -> submit("Send", validate _)
)
}
form_ajax.html
<lift:surround with="default" at="content">
Enter your first and last name:<br>
<form class="lift:FormWithAjax?form=post">
First Name: <form:first></form:first>
Last Name: <form:last></form:last>
<form:submit></form:submit>
</form>
</lift:surround>
And this will work without javascript:
<form action="/form_ajax" method="post">
<input name="F1069091373793VHXH01" type="hidden" value="true">
First Name: <input value="" type="text" name="F1069091373788OVAAWQ" onblur="liftAjax.lift_ajaxHandler('F1069091373789N2AO0C=' + encodeURIComponent(this.value), null, null, null)">
Last Name: <input value="" type="text" name="F1069091373790VANYVT" onblur="liftAjax.lift_ajaxHandler('F1069091373791CJMQDY=' + encodeURIComponent(this.value), null, null, null)">
<input name="F1069091383792JGBYWE" type="submit" value="Send">
</form>
I dont know a lot about Lift so my answer focuses on alternate way to do it.
This is jQuery based and will do with AJAX when Javascript is usable and traditional POST if there is no Javascript support enabled.
Form:
<form id="ajaxform" action="formhandler.php" method="post" enctype="multipart/form-data" >
<input name="firstname" type="text" />
<input name="email" type="email" />
<input name="accept" type="submit" value="Send" />
</form>
<div id="result"></div>
JS:
note: jQuery $.ajax() sends as application/x-www-form-urlencoded by default, it may be good to set form enctype="application/x-www-form-urlencoded" too.
$("#ajaxform").submit(function(e){
// Alternative way to prevent default action:
e.preventDefault();
$.ajax({
type: 'POST',
url: 'formhandler.php',
// Add method=ajax so in server side we can check if ajax is used instead of traditional post:
data: $("#ajaxform").serialize()+"&method=ajax",
success: function(data){ // formhandler.php returned some data:
// Place returned data <div id="result">here</div>
$("#result").html(data);
}
});
// Prevent default action (reposting form without ajax):
return false;
});
Server side (PHP)
<?php
if (isset($_POST['method']) && $_POST['method'] == 'ajax') {
// AJAX is used this time, only #result div is updating in this case.
} else {
// Traditional POST is used to send data, whole page is reloading. Maybe send <html><head>... etc.
}
?>
What About REST then?
This is something you should decide to use or to not use, it is not something to support as alternate to other methods (ajax, traditional) but more something integrate within other methods.
Of course you can always enable or disable REST feature.
You can always make form method="POST/GET/PUT/DELETE" and ajax call RESTful:
...
$.ajax({
type: 'PUT',
url: 'formhandler.php',
...
...
$.ajax({
type: 'DELETE',
url: 'formhandler.php',
...
But REST asks us to use XML, JSON, ... for requests too
Well, that is not well supported by browsers (without Javascript) but $.ajax() uses application/x-www-form-urlencoded as default encoding.
Ofcourse, with Javascript one can always convert data container to XML or JSON ...
Here's how it can be done with jQuery, JSON object:
/* This is function that converts elements to JSON object,
* $.fn. is used to add new jQuery plugin serializeObject() */
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
But I want one AJAX call that does everything:
You are right, computers should do our work. It's what they are designed for.
So, another thing that needs to be done is to check what http method our original html form wants to use and adapt it to send ajax requests with same method that would be used without javascript support.
This is modified version from under JS: heading used earlier:
...
// Alternative way to prevent default action:
e.preventDefault();
// Find out what is method that form wants to use and clone it:
var restmethod = $('#ajaxform').attr('method');
// Put form data inside JSON object:
var data = $('#orderform').serializeObject();
// Add method=ajax so in server side we can check if ajax is used instead of traditional post:
data.method = 'ajax';
$.ajax({
type: restmethod, // Use method="delete" for ajax if so defined in <form ...>
url: 'formhandler.php',
data: data, // data is already serialized as JSON object
...
Now, our AJAX handler sends data as JSON object using method (post|get|put|delete) that is defined at <form method="put" ...>, if form method changes then our ajax handler will adapt changes too.
That's all, some code tested and is actually in use, some is not tested at all but should work.

Trying to check each form input and blank its default value in jquery ajaxform()

I am using the ajaxform() plugin, which so far is working well. However, my input fields have default values, and if the user just submits the untouched form, I need to blank them out before the form is submitted using the beforeSubmit: callback.
In nutshell, I don't know the syntax to check the forms input fields and stop the submit if necessary. I have an idea its using the each() method and this.defaultValue, and maybe a return false? but I'm not sure of the details.
Could anyone perhaps give me an idea? Thanks. Heres my code so far, its the checkValues() function that I'm stuck with.
$(document).ready(function(){
//========= Functions =========
function styleForm() {
$('.quickcontact label').hide();
$('input[type="text"],textarea').addClass("idleField");
$('input[type="text"],textarea').focus(function() {
$(this).removeClass("idleField").addClass("focusField");
if (this.value == this.defaultValue){
this.value = '';
}
if(this.value != this.defaultValue){
this.select();
}
});
$('input[type="text"],textarea').blur(function() {
$(this).removeClass("focusField").addClass("idleField");
if ($.trim(this.value) == ''){
this.value = (this.defaultValue ? this.defaultValue : '');
}
});
}
//options for ajaxform() function
var options = {
target: '.quickcontactDisplay', // target element(s) to be updated with server response
beforeSubmit: checkValues, // pre-submit callback
success: reBind // post-submit callback
// other available options:
//url: url // override for form's 'action' attribute
//type: type // 'get' or 'post', override for form's 'method' attribute
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
//clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
// $.ajax options can be used here too, for example:
//timeout: 3000
};
//rebinds the ajax functionality to updated form html
function reBind() {
// re-do the form, as it has just been replaced
$('form.quickcontact').ajaxForm(options);
styleForm();
}
//checks for default values of form on submit to prevent them being submitted
function checkValues(){
}
// ==== logic =====
$('form.quickcontact').ajaxForm(options);
styleForm();
});
And my form html:
<form action="/enquiries/add" method="post" id="EnquiryAddForm" class="quickcontact">
<input type="hidden" value="POST" name="_method"/>
<input type="hidden" id="EnquiryVisitorId" value="276" name="data[Enquiry][visitor_id]"/>
<input type="text" id="EnquiryName" maxlength="200" value="Your name" name="data[Enquiry][name]"/>
<input type="text" id="EnquiryEmailAddress" maxlength="200" value="Your Email" name="data[Enquiry][emailAddress]"/>
<textarea id="EnquiryEnquiry" rows="6" cols="30" name="data[Enquiry][enquiry]">Your Email Address</textarea>
<input type="submit" value="Ok, I'm done"/>
</form>
You are abusing the default value as a label. This is causing you problems. Rather then trying to work around those problems, I suggest fixing the cause instead.
When setting default values — set default values. Don't use the default value as a pseudo-label. Use a <label> element instead.
Haven't you looked at the documentation?
beforeSubmit:
Callback function to be invoked before the form is submitted. The
'beforeSubmit' callback can be
provided as a hook for running
pre-submit logic or for validating the
form data. If the 'beforeSubmit'
callback returns false then the form
will not be submitted. The
'beforeSubmit' callback is invoked
with three arguments: the form data in
array format, the jQuery object for
the form, and the Options Object
passed into ajaxForm/ajaxSubmit. The
array of form data takes the following
form:
[ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
Default value: null
Here the idea, didn't check it yet.
function checkValues(formData, jqForm, options)
{
for( var i in formData)
if ( formData[i].value == "")
return false;
return true;
}
sounds as if you need to:
run through all the inputs / textarea at the start and grab the default values, then stick it into an associative array with the element id as key
within checkValues, iterate through inputs once again and compare the pre-submit value against your array - when finding a match, you can set the value to "".

Resources