I have a JQuery-created widget that generates input fields into divs that have prespecified and distinct ids. I'm having difficulty with form validation in the instance where I have two of these input field widgets on the same page. The first widget instance works fine, but the second instance seems to be responding to the input fields in the first instance and not its own input fields.
I realize that my code has the problem where I have elements with the same id -- not sure how best to get around this. Would appreciate help either in how to correctly identify the value of a specific input field or adding JQuery to my form creation code to create unique instances.
Here are the html containers:
<div id="login">
</div>
<div id="otherDiv">
</div>
Here's the JQuery widget:
$.widget("custom.login", {
// default options
options: {
action:null
},
// the constructor
_create: function() {
console.log(this.options.id);
var html = '';
$(this.element).addClass("custom-login");
html += '<form id="loginForm" action="' + (this.options.action||'') + '">'
html += '<div id="container">';
html += '<label id="loginTitleText">User Login</label>';
html += '<div class="spacer"></div>';
html += '<div class="field" id="loginDiv"><input type="text" placeholder=" Apple ID" id="loginUser"/></div>';
html += '<div class="spacer"></div>';
html += '<div class="field" id="passwordDiv"><input type="password" placeholder=" Password" id="loginPassword"/></div>';
html += '<div class="spacer"></div>';
html += '<div class="field" id="submitDiv"><input type="submit" class="submitButton" value="Login to your account"/></div>';
html += '</div>';
html += '</form>';
$(this.element).html(html);
if(this.options.submit){
$('form', this.element).submit(this.options.submit);
}
this._refresh();
And here is the validation code:
$("#login").login({submit:function(e){
var x=document.forms["loginForm"]["loginUser"].value;
var y=document.forms["loginForm"]["loginPassword"].value;
if (x==null || x=="" || y==null || y==""){
alert("Please fill out all fields");
return false;
}
$("#otherDiv").login({submit:function(e){
var x=document.forms["loginForm"]["loginUser"].value;
var y=document.forms["loginForm"]["loginPassword"].value;
if (x==null || x=="" || y==null || y==""){
alert("Please fill out all fields");
return false;
}
Thanks!
Related
Hello everyone I'm still new to JS, so I want to ask about calling a function when form is submitted.
[update] Form
<div id="dashboard-side">
<form id="report" class="form-horizontal" method="post" action="<?= site_url('api/load_report') ?>"> <!-- onsubmit="location.reload()" -->
<fieldset>
<div class="control-group center_div">
<label class="control-label">Sales Name</label>
<div class="controls">
<input type="text" name="sales_name" class="form-control input-xlarge txt-up" value="<?php echo set_value('cust_name'); ?>" placeholder="Enter Customer Name" style="height: 30px;"/>
</div>
</div>
<div class="control-group center_div">
<div class="controls form-inline">
<input id="get_report" type="submit" class="btn btn-success btn-inline " value="Get Report" style="width:110px; margin-left: -155px;"/>
</div>
</div>
<table border="1" width="100%" style="background-color: #dfe8f6;">
<tr>
<td width="154px"><strong>Customer Name</strong></td><td width="128px"><strong>Activity</strong></td>
<td width="244px"><strong>Detail</strong></td><td width="141px"><strong>Start Time</strong></td>
<td width="142px"><strong>Finish Time</strong></td><td width="39px" style="text-align:center"><strong>Note</strong></td>
<td style="margin-left: 50px"><strong>Action</strong></td>
</tr>
</table>
<!------------------------------------------------------------------------------------->
<div id="xreport" class="table-hover" style="background-color: #EAF2F5"></div>
</fieldset>
</form>
</div>
Controller
public function load_report() {
$this->db->where('user_id', $this->input->post('sales_name'));
$query = $this->db->get('activity');
$result = $query->result_array();
$this->output->set_output(json_encode($result)); }
JS
var load_report = function() {
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
};
If I call the function on form load it works fine, but I want to call it on form submit, how to do that?
Here is what I tried
var load_report = function () {
$("#report").submit(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
});
};
Instead of assigning the array into my #div, it shows the array data in the new blank tab like this:
my current result so far
any help would be appreciated, thanks.
Update: New calling function
var load_report = function () {
$("#report").submit(function (evt) {
evt.preventDefault();
var url = $(this).attr('action');
var postData = $(this).serialize();
$.post(url, postData, function (o) {
if (o.result == 1) {
var output = '';
Result.success('Clocked-in');
for (var i = 0; i < o.length; i++) {
output += Template.dodo(o[i]); //this data[0] taken from array in api/load_report
console.log(output);
$("#xreport").html(output);
}
} else {
Result.error(o.error);
console.log(o.error);
}
}, 'json');
});
};
with this new calling function I'm able to retrieve data from api/load_report without getting stuck on e.preventDefault or even open a new tab, I console.log and the result show correctly in the console, but it doesn't show on the div somehow.
my template.js (if needed)
this.dodo = function(obj){
var output ='';
output +='<table border=1, width=100%, style="margin-left: 0%"';
output += '<tr>';
output += '<td width=120px>' + obj.user_id + '</td>';
output += '<td width=120px>' + obj.cust_name + '</td>';
output += '<td width=100px>' + obj.act_type + '</td>';
output += '<td width=190px>' + obj.act_detail + '</td>';
output += '<td width=110px>' + obj.date_added + '</td>';
output += '<td width=110px>' + obj.date_modified + '</td>';
output += '<td style="text-align:center" width=30px>' + obj.act_notes + '</td>';
output += '</tr>';
output +='</table>';
output += '</div>';
return output;
};
Result (note, user_id = form.sales_name)
result preview
First off, I would advise against using onclick or onsubmit directly on the dom like so.
<form onsubmit="myFunction();"></form>
The biggest reason for me is that it negatively impacts readability and sometimes even future maintenance of the project . It is nice to keep html and javascript separate unless you are using a framework that provides templating features/functionality such as angularjs.
Another big one is that you can only have one in-line event present and it is easy to accidentally overwrite, which can lead to confusing bugs.
The reason it is going to a new tab is because of the .submit(). This will call your function, but then proceed with internal jQuery event handling which includes refreshing the page. There are two solutions I see most viable here.
1st Solution:
Add a event.preventDefault(); at the start of your function to stop jQuery from refreshing your page.
$("#report").submit(function(e) {
e.preventDefault();
});
2nd Solution (Likely better):
You are making an ajax call with $.get(...). You could add an event listener on a button (probably on the button used to submit the form) that fires your ajax call. Here is an example that assumes the submit button has the id of loadData.
$("#loadData").click(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
You could alway do the following:
function myFunction() {
alert("Hello! I am an alert box! in a function");
}
<form>
<input type="text" />
<input type="submit" value="submit" onclick="return myFunction();"/>
</form>
P.S. This question might be answered in this question already, add onclick function to a submit button
Try to prevent form to get submit by using preventDefault()
$("#report").submit(function(e){ //add param "e"
e.preventDefault(); //to prevent form to submit
//further code....
});
Ok just try
function mysubmit(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
as your script and
<form id="report" class="form-horizontal" onsubmit="event.preventDefault(); mysubmit();" method="post" action="<?= site_url('api/load_report') ?>">
as your form
Similar Issue
This post is similar to what I wanted, but not a particular solution to what I am seeking.
My Issue
I want the user to input Genesis 1 then click submit, and the html pushes a submit request to my bible_api_pull.js which launches an ajax call to update the index.html page with that chapters text asynchronously.
Current State of the Project
My html page: here
My Ajax call on submit: here
The actual website: here
And my end goal was to store this information into a database with id, bookName, chapterNumber, and chapterText based on what the user pulled. However, I can't even seem to get the API populating the page correctly.
Other Resources
I got the main API call code from the api information here.
Edit: Reproducible Example
So I have a container holding 2 inputs, #bookInput and #chapterInput. On submit they are successfully getting read into my bible_api_pull.js file below. However, it is not populating. Things I've tried:
Alerts will not work inside of the submit function call.
Updating a new div in my html to see whats going on inside of that api call that isn't working, but nothing gets read.
I am wondering if it is something very subtle I am missing, or if this really is a logic error in my understanding of javascript/ajax.
<!-- index.html -->
<div class="container">
<div class="jumbotron">
<form id="target" class="form-inline" action="" method="">
<label class="sr-only" for="inlineFormInput">Book</label>
<input id="bookInput" name="bookId" type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" placeholder="Search book ...">
<label class="sr-only" for="inlineFormInput">Chapter</label>
<input id="chapterInput" name="chapterId" type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" placeholder="Search chapter ...">
<button type="submit" class="btn btn-primary" style="">Submit</button>
<img src="../images/ajax-loader.gif" id="loading-indicator" style="display:none;position:absolute;top:"+$(window).height()/2+"px;left:"+$(window).width()/2+"px;" />
</form>
<hr>
<div id="scripture"> </div>
</div>
</div>
// bible_api_pull.js
$('#target').submit(function(event){
// Next up ... dynamically accept the users choice!!!! Each input has it's own ID now!
$('#loading-indicator').show();
// Load the data
var book = $("#bookInput").val();
var chapter= $("#chapterInput").val();
//var keywordInput = $("#searchInput").val();
var book_chapter = book+chapter;
// Pass the data
jQuery.ajax({
url:'http://getbible.net/json',
dataType: 'jsonp',
data: 'p='+book_chapter+'&v=kjv',
jsonp: 'getbible',
success:function(json){
// set text direction
if (json.direction == 'RTL'){
var direction = 'rtl';
} else {
var direction = 'ltr';
}
/********************************************/
/* Formatting for verses being returned */
/********************************************/
if (json.type == 'verse'){
var output = '';
jQuery.each(json.book, function(index, value) {
output += '<center><b>'+value.book_name+' '+value.chapter_nr+'</b></center><br/><p class="'+direction+'">';
jQuery.each(value.chapter, function(index, value) {
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
});
output += '</p>';
});
jQuery('#scripture').html(output); // <---- this is the div id we update
}
/********************************************/
/* Formatting for chapters being returned */
/********************************************/
else if (json.type == 'chapter'){
var output = '<center><h3><b>'+json.book_name+' '+json.chapter_nr+'</b></h3></center><br/><p class="'+direction+'">';
jQuery.each(json.chapter, function(index, value) {
if(value.verse.includes(keywordInput)){
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
}
});
output += '</p>';
jQuery('#scripture').html(output); // <---- this is the div id we update
}
/********************************************/
/* Formatting for books being returned */
/********************************************/
else if (json.type == 'book'){
var output = '';
jQuery.each(json.book, function(index, value) {
output += '<center><h1><b>'+json.book_name+' '+value.chapter_nr+'</b></h1></center><br/><p class="'+direction+'">';
jQuery.each(value.chapter, function(index, value) {
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
});
output += '</p>';
});
if(addTo){
jQuery('#scripture').html(output); // <---- this is the div id we update
}
}
$('#loading-indicator').hide();
},
error:function(){
jQuery('#scripture').html('<h2>No scripture was returned, please try again!</h2>'); // <---- this is the div id we update
},
});
event.preventDefault();
});
I didnt understand what was your issue?
But anyway this code is quite straight forward.
I commented if(value.verse.includes(keywordInput)){ because var keywordInput = $("#searchInput").val(); variable was commented during declaration and it's working now. Check the response and let me know what exactly you wanted.
$('#target').submit(function(event){
// Next up ... dynamically accept the users choice!!!! Each input has it's own ID now!
//$('#loading-indicator').show();
// Load the data
var book = $("#bookInput").val();
var chapter= $("#chapterInput").val();
//var keywordInput = $("#searchInput").val();
var book_chapter = book+chapter;
// Pass the data
jQuery.ajax({
url:'http://getbible.net/json',
dataType: 'jsonp',
data: 'p='+book_chapter+'&v=kjv',
jsonp: 'getbible',
success:function(json){
// set text direction
if (json.direction == 'RTL'){
var direction = 'rtl';
} else {
var direction = 'ltr';
}
/********************************************/
/* Formatting for verses being returned */
/********************************************/
if (json.type == 'verse'){
var output = '';
jQuery.each(json.book, function(index, value) {
output += '<center><b>'+value.book_name+' '+value.chapter_nr+'</b></center><br/><p class="'+direction+'">';
jQuery.each(value.chapter, function(index, value) {
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
});
output += '</p>';
});
jQuery('#scripture').html(output); // <---- this is the div id we update
}
/********************************************/
/* Formatting for chapters being returned */
/********************************************/
else if (json.type == 'chapter'){
var output = '<center><h3><b>'+json.book_name+' '+json.chapter_nr+'</b></h3></center><br/><p class="'+direction+'">';
jQuery.each(json.chapter, function(index, value) {
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
});
output += '</p>';
jQuery('#scripture').html(output); // <---- this is the div id we update
}
/********************************************/
/* Formatting for books being returned */
/********************************************/
else if (json.type == 'book'){
var output = '';
jQuery.each(json.book, function(index, value) {
output += '<center><h1><b>'+json.book_name+' '+value.chapter_nr+'</b></h1></center><br/><p class="'+direction+'">';
jQuery.each(value.chapter, function(index, value) {
output += ' <small class="ltr">' +value.verse_nr+ '</small> ';
output += value.verse;
output += '<br/>';
});
output += '</p>';
});
if(addTo){
jQuery('#scripture').html(output); // <---- this is the div id we update
}
}
$('#loading-indicator').hide();
},
error:function(){
jQuery('#scripture').html('<h2>No scripture was returned, please try again!</h2>'); // <---- this is the div id we update
},
});
event.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="jumbotron">
<form id="target" class="form-inline" action="" method="">
<label class="sr-only" for="inlineFormInput">Book</label>
<input id="bookInput" name="bookId" type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" placeholder="Search book ...">
<label class="sr-only" for="inlineFormInput">Chapter</label>
<input id="chapterInput" name="chapterId" type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" placeholder="Search chapter ...">
<button type="submit" class="btn btn-primary" style="">Submit</button>
</form>
<hr>
<div id="scripture"> </div>
</div>
</div>
I hope you understand :)
I am creating a web page which includes a very simple subscription form, basically collecting the email addresses of those interested in the product. For this form I am using rapidmail, which offers a service similar to mailchimp. My issue is that after the email address has been entered, the user is being redirected to a new page where a success (or error, in case the email address was faulty) message is displayed. What I want is for these messages to be displayed on the same page as the form, because the page I am being redirected to is, well, ugly. Rapidmail also offers the alternative to use an iframe, which interestingly enough displays success/error messages on the same page as the form; it is unfortunately equally ugly and its customizing options are very limited and do not fit the design of my page.
I was hoping that a solution like this would be possible, thopugh I do not know if rapidmail provides an "alternative endpoint" that allows me to "work with JSON" as in the link.
this is what my form looks like (pretty standard)
<form action="https://tools.emailsys.net/121/1550/18cxn42/subscribe/form.html" method="post">
<div class="form">
<div class="form_border">
<ul>
<li>
<label class="field_label required" for="email">E-Mail: </label>
<input type="text" class="form_field" name="email" id="email" value="" />
</li>
<li id="firstname_form">
<label id="firstname_label" class="field_label" for="firstname">Vorname: </label>
<input type="text" class="form_field" name="firstname" id="firstname" value="" />
</li>
<li class="form_button">
<input type="submit" class="form_button_submit" value="Anmelden" />
</li>
</ul>
</div>
</div>
</form>
JS:
/*
* Get errors of RapidMail forms
*/
var rapidmail_form = document.getElementById('rapidmail_form');
if (typeof(rapidmail_form) != 'undefined' && rapidmail_form != null && rapidmail_form.length)// if we have a RapidMail form
{
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
vars[key] = value;
});
return vars;
}
// email
var field_email = getUrlVars()["field_email"];
if (field_email.length > 0) {
document.getElementById("email").value = field_email;// get previous email
}
// lastname
var field_lastname = getUrlVars()["field_lastname"];
if (field_lastname.length > 0) {
document.getElementById("lastname").value = field_lastname;// get previous lastname
}
// Error message
var error_email = getUrlVars()["error_email"];
var error_lastname = getUrlVars()["error_lastname"];
// Gather all errors into one.
var error_text = '';
// error_email
if (error_email != 'undefined' && error_email != null && error_email.length > 0) {
error_email = error_email.replace(/\+/g, ' ');
error_text += '<p>' + error_email + '</p>';
}
// error_lastname
if (error_lastname != 'undefined' && error_lastname != null && error_lastname.length > 0) {
error_lastname = error_lastname.replace(/\+/g, ' ');
error_text += '<p>' + error_lastname + '</p>';
}
// Input gathered text to h5
if (document.getElementById("rapidmail_form_error") != 'undefined' && document.getElementById("rapidmail_form_error") != null) {
document.getElementById("rapidmail_form_error").innerHTML = error_text;// show Error
}
}
HTML:
<div id="rapidmail_form_error"></div>
<form action="https://tools.emailsys.net/121/1550/18cxn42/subscribe/form.html" method="post" id="rapidmail_form">
So it looks at the URL RapidMail generates and parse it. Finally it gathers all errors and paste it to rapidmail_form_error id element.
Just put the current URL to:
<input type="hidden" name="url_error" value="THE_URL_OF_YOUR_FORM" />
I have the following JS code which use's local storage to display the 'name' and 'age' entered previously:
This HTML code currently displays the date, time, name and age of a person in a table. how can i pass these values to be displayed in a HTML form as labels instead of in that table?
HTML only bringing back the start time, name and age aren't being displayed:
<div id="history_list"></div>
<div id="name"> </div>
<div id="age"></div>
JS:
function loadHistoryList() {
for(var i = numberOfHistory; i >= 1; i--) {
var historyData = new historyElement(db.getItem(i.toString()));
if(historyData === null) {
console.error('error');
continue;
}
$('#history_list').append(historyData.startTime);
$('#name').append(historyData.name);
$('#age').append(historyData.age);
}
}
instead of
var div = '<div id="history_element"><div id="element_title">' + historyData.startDate + ' ' + historyData.startTime + '</div><table>';
var div = '<div id="name"><tr><td>name: </td><td>' + historyData.name+ '</td></tr>';
var div = '<div id="age"><tr><td>age: </td><td>' + historyData.age+ '</td></tr>';
div += '</table></div>';
$('#history_list').append(div);
$('#name').append(div);
$('#age').append(div);
Do this:
$('#history_list').append(historyData.startTime);
$('#name').append(historyData.name);
$('#age').append(historyData.age);
In short: you can (and should in this case) simply add the desired value to the container (the DIV, Form field, or whatnot)
those three lines starting witn var div (...) are overwriting each previous line, but that is a side note.
Overall, you should read up more on JavaScript and/or JQuery.
To populate the form field First you have to add a form element like input field
HTML
<div id="history_list">
</div>
<input type="text" id="name" name="name">
JS
function loadHistoryList() {
for(var i = numberOfHistory; i >= 1; i--) {
var historyData = new historyElement(db.getItem(i.toString()));
if(historyData === null) {
console.error('error');
continue;
}
$('#name').val(historyData.name);
}
}
Created a basic input textbox and a button dynamically via javascript using some bootstrap css. On pressing the button I need to retrieve the value of the textbox. But its coming out to be empty (not undefined).
The doSearch function is where I need to pick up the value.
Here is the jsFiddle: http://jsfiddle.net/9u3kb6rk/3
Here is the code:
(function ($) {
function doSearch() {
alert($('#name').val());//this is empty?
}
$(document.body).on('click', '#go', function () {
alert('doing search');
doSearch();
});
$.fn.searchName = function () {
var caller = $(this);
var output = '';
output += '<div class="input-group ">';
output += '<span class="input-group-addon area" id="name" name="name">Name</span>';
output += '<input type="text" class="form-control" />';
output += '</div>';
output += '<div class="input-group">';
output += '<span class="input-group-btn">';
output += '<button class="btn btn-primary" type="button" id="go">Search</button>';
output += '</span>';
output += '</div>';
output += '</div>';
$(caller).html(output);
return this;
}
}(jQuery));
$(document).ready(function () {
$('#searchName').searchName();
});
The id must be in the input instead of in the span.
output += '<span class="input-group-addon area">Name</span>';
output += '<input type="text" id="name" name="name" class="form-control"
Your code updated.