Ajax Form Submit not loading newly submitted data - javascript

I updated jquery so i could play with the new jquery mobile ui 1.3 and for some reason my form no longer update page any more, it worked previously but it wasn't through ajax, it simply submitted the form without ajax, I would however like ajax to just fetch the new data and append it to the div instead of reloading the whole page again when the popup closes.
I use a popup module for the form and on submission it should append the new information to #content ul
The JS.
<!-- Load Json data and events -->
<script type="text/javascript">
jQuery('#new_rave').live('submit',function( event ) {
$.ajax({
url: 'http://whoops/goodtimes',
type: 'POST',
dataType: 'json',
data: $('#new_rave').serialize(),
success: function( data ) {
for( var id in data ) {
jQuery('#').html(data[id]);
}
}
});
return false;
});
$(document).ready(function() {
$.getJSON('http://whoops/goodtimes', function( goodtimes ) {
$.each(goodtimes, function( goodtime ) {
var output =
"<li><a href="+this.goodtime.id+">" +
"<h3>" + this.goodtime.title + "</h3>" +
"<p>" + this.goodtime.post + "</p>" +
"<p class='ui-li-aside'><strong>" +
this.goodtime.created_at + "</strong></p>" +
"</a></li>";
$('#content ul').append(output).listview('refresh');
});
});
});
</script>
The form
<!-- New item Popup -->
<div data-role="popup" class="ui-content"
data-overlay-theme="a" data-position-to="window" id="add">
<form id="new_rave">
<label for="goodtime_title">Title</label>
<input type="text" name="goodtime[title]" id="goodtime_title">
<label for="goodtime_post">Rave</label>
<div data-role="fieldcontain">
<textarea name="goodtime[post]" id="goodtime_post"></textarea>
</div>
<input type="submit" value="submit">
</form>
</div>
and the content div
<div id="content" data-role="content">
<ul data-role="listview" data-theme="d" data-divider-theme="d"></ul>
</div><!-- /content -->

Intro
Your problem is probably due to $(document).ready(function(){. In jQuery Mobile, Ajax is used to load the content of each page into the DOM as you navigate. Because of this $(document).ready() will trigger before your first page is loaded and every code intended for page manipulation will be executed after a page refresh.
Everything here can be found described with more details in my personal blog article.
In case this is not a problem, use Firefox/Chrome plugin Firebug to test if ajax call has reached a server and if response has been received.
Last thing, don't refresh listview every time you append a new element. listview refresh is a huge time sink, every refresh can last around 50ms but do it numerous time and your restyling could go forever.
Solution
So change this:
$.getJSON('http://whoops/goodtimes', function(goodtimes) {
$.each(goodtimes, function(goodtime) {
var output =
"<li><a href="+this.goodtime.id+">" +
"<h3>" + this.goodtime.title + "</h3>" +
"<p>" + this.goodtime.post + "</p>" +
"<p class='ui-li-aside'><strong>" + this.goodtime.created_at + "</strong></p>" +
"</a></li>";
$('#content ul').append(output).listview('refresh');
});
});
to this:
$.getJSON('http://whoops/goodtimes', function(goodtimes) {
$.each(goodtimes, function(goodtime) {
var output =
"<li><a href="+this.goodtime.id+">" +
"<h3>" + this.goodtime.title + "</h3>" +
"<p>" + this.goodtime.post + "</p>" +
"<p class='ui-li-aside'><strong>" + this.goodtime.created_at + "</strong></p>" +
"</a></li>";
$('#content ul').append(output);
});
$('#content ul').listview('refresh');
});
EDIT
Your problem with constant post repeating comes to how jQuery Mobile handles event binding. Because pages are constantly revisited each time events are going to be bound over and over. In your case that would be an event that executes JSON call.
This can be prevented in several ways, most common one is to unbind event before binding it. For example:
$('#test-button').off('click').on('click', function(e) {
alert('Button click');
});

Related

Create a button that links to a html page for each item in database using javascript

Im trying to create buttons for each item shown in a list from my database. currently i have the list displayed using Ajax to a PHP file.
More info: Currently this code pulls and lists all questions from a SQL database. for every value in the list the code displays it in the "DOM" div class. I would like to include a button that links to advice.html for every item in the list.
HTML:
<body>
<!--output of the json-->
<div>
<!--set the id to DOM to show output-->
<div id="DOM">
</div>
</div>
insert
delete
show data
login
register
</body>
Javascript:
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: "http://localhost/api/fetchdata.php",
type: "POST",
dataType: "json",
data: "param=no",
//on success it will call this function
success: function (data) {
var DOM = $('#DOM');
$.each(data, function (key, value) {
DOM.append("<h3>" + value.Subject + "</h3><p>" + value.Description + "</p>", $('<input type="button" href="localhost/advice.html" value="respond">')););
});
//if fail it will give this error
}, error: function (e) {
alert("failed to work");
}
});
});
</script>
I guess the line
DOM.append("<h3>" + value.Subject + "</h3><p>" + value.Description + "</p>", $('<input type="button" href="localhost/advice.html" value="respond">')););
can be replaced with
DOM.append("<h3>" + value.Subject + "</h3><p>" + value.Description + "</p>", $('<button>respond</button>')););

Dynamically added code not responding to jQuery click

I have read several questions on this forum about this problem, but it still not work for me. All other buttons and clickable elements that are in the code from the beginning works fine, but not those element that is passed dynamically. Everything works when I run the page local, but online it's not working. What could be wrong?
This is part of the dynamically code: (The data[i].id comes from an Ajax request)
html += "<td width='20px'>" + status + "</td><td class='updateCompleted' data-id='" + data[i].id + "'>" + data[i].text + "</td><td align='right' width='20px'><img src='icons/icon-remove.png' alt='remove icon' class='removeIcon' data-id='" + data[i].id + "'></td>";
I then add the code like this:
$(".contentList table").html(html);
And this is the jQuery to detect the click:
// Handle click to set row in list to completed
$(document).on("click",".updateCompleted", function(e){
e.preventDefault();
var id = $(this).data("id");
updateData(id,1)
console.log("Test");
});

Make jquery plugin work on multiple instances

I am looking to buil a jquery plugin that will transform a link to a hidden form and fill some fields.
The form will be used to post json data to a method in the back end.
The class starts the work and I can set custom settings. The issue is when I have more than one export needed on each page the settings are only using the last iteration.
See below for more clarification.
Init the plugin with the class and add the processing link
$(".export-csv").exportCSV({
link: '{$base_url}ajax/export-csv'
});
Here I have two links for exporting data.
I pass through the title and data (smarty templating system)
<li>
<a href="#" class="export-csv"
data-title='Landlords'
data-data='{$landlords_json}'>Export Landlords (CSV)</a>
</li>
<li>
<a href="#" class="export-csv"
data-title='Buyers'
data-data='{$buyers_json}'>Export Buyers (CSV)</a>
</li>
When I click either button it will give me the buyers export as it was latest in the loop.
The forms are showing the correct data when I inspect the page. It must be the settings.title and settings.data that are getting caught.
I can see its due to the position in the loop but I am unsure how to fix this.
(function($) {
$.fn.exportCSV = function ( options ) {
var settings = $.extend({
title: null,
data: null,
link: '/',
link_text: 'Export (CSV)',
}, options);
return $(this).each( function () {
settings.title = $(this).data('title');
settings.data = JSON.stringify( $(this).data('data') );
var hidden_form = "<form id='" + settings.title.toLowerCase() + "-export-csv' action='" + settings.link + "' method='POST' style='display: none;'>" +
"<input type='hidden' name='title' value='" + settings.title + "'>" +
"<input type='hidden' name='data' value='" + settings.data + "'>" +
"</form>";
$(this).append(hidden_form);
$(this).on('click', function () {
console.log( $(this) );
event.preventDefault();
$('#' + settings.title.toLowerCase() + '-export-csv').submit();
});
});
}
}(jQuery));

Javascript dynamic switch doubling Ajax calls

I am having a problem with a jQuery click function. When a user clicks a HTML button, my jQuery dynamically loads some styled checkbox's/toggle switches based upon their corresponding on/off state stored in a database.
I then added a click function to each dynamically loaded toggle switch so that when a user clicks it, it updates the database with the new state, it then, with Ajax, calls the GetAllSwitches function again loading the current state of the switches from the DB back into the resultScreen.
It works, updates the state in the DB correctly, but the program remembers previous 'clicks' and runs them all again followed by the new click state every time a user clicks. So on the first click it makes 1 http request, 2nd 2, 3rd 4, 4th 8 etc. The problem being after a few clicks the ajax calls become huge.
I'm not that experienced in Javascript so I am aware my code is verbose and I am clearly missing something, but are there any fixes or better approaches to this?
In summary what I want to achieve is:
User clicks allSwitches
Ajax call to a database which returns all objects with a toggle switch on screen
Have the toggle switch's clickable which updates the database with new state
Allow the switches to be clicked as many times as the user likes only making one update to the DB
HTML
<fieldset>
<legend> Get All Lights Dynamically</legend>
<input type="button" value="Show All" id="allSwitches"/>
</fieldset>
<fieldset>
<div id='resultScreen'></div>
</fieldset>
JavaScript
$(document).ready(function(){
$("#allSwitches").click(function(){
$.ajax({
url: 'GetAll',
type: 'GET',
dataType: 'text',
success: function(data) {
getAllSwitches(data)
});
});
});
function getAllSwitches(data){
var tr;
myData = $.parseJSON(data);
for(var i = 0; i < myData.length; i++){
tr = $('<tr/>');
if(myData[i].state=="On"){
tr.append('<div id="togs' + i + '">' + '<label class="switch">' +
'<input type="checkbox" class="' + myData[i].lightName +'" checked>' +
'<div class="slider round"></div>'
+'</label>' + '</div>');
tr.append("<td>" + myData[i].lightName +
" is " + myData[i].state + "</td>");
$('#resultScreen').append(tr);
var className = '.' + myData[i]lightName;
var lightName = myData[i].lightName;
var state = "Off";
upTog(className, lightName, state);
} else if (myData[i].state=="Off"){
tr.append('<label class="switch">' +
'<input type="checkbox" class="' + myData[i].lightName +'" >' +
'<div class="slider round"></div>'
+'</label>');
tr.append("<td>" + myData[i].lightName +
" is " + myData[i].state + "</td>");
$('#resultScreen').append(tr);
var className = '.' + myData[i].lightName;
var lightName = myData[i].lightName;
var state = "On";
upTog(className, lightName, state);
}
}
}
function upTog(className, lightName, state){
$(document).on('click', className, function() {
$.ajax({
url: 'UpdateLight?lightName=' + lightName + "&state=" + state,
type: 'POST',
dataType: 'text',
success:function(data){
$.ajax({
url: 'GetAll',
type: 'GET',
dataType: 'text',
success: function(data) {
$('#resultScreen').empty();
getAllSwitches(data);
}});
}
})
});
}
Many thanks.
The easiest way to do it is to unbind the previous click before set the new one.
Change upToge() body like this:
$(className).unbind( "click" );
$(className).on('click', function () {
/* Your ajax call here */
});
You're adding the click handler to the className, which is not changing when you empty the #resultsScreen div. You can see how the handlers pile up in this jsbin: http://jsbin.com/hizigutogi/edit?js,console,output (fill the div, click the red box, empty it, fill it again, and click it a few more times)
Try passing the reference to the jQuery object tr into upTog and adding the click handler onto it directly, instead of attaching it to the class name.

HTML submit text used for Javascript query with API

For a project, I am trying to make a HTML form that when a movie is searched it can access the Rotten Tomatoes API and queries the user's submitted text and returns with the movie.
The javascript* code from Rotten Tomatoes was provided
<script>
var apikey = "[apikey]";
var baseUrl = "http://api.rottentomatoes.com/api/public/v1.0";
// construct the uri with our apikey
var moviesSearchUrl = baseUrl + '/movies.json?apikey=' + apikey;
var query = "Gone With The Wind";
$(document).ready(function() {
// send off the query
$.ajax({
url: moviesSearchUrl + '&q=' + encodeURI(query),
dataType: "jsonp",
success: searchCallback
});
});
// callback for when we get back the results
function searchCallback(data) {
$(document.body).append('Found ' + data.total + ' results for ' + query);
var movies = data.movies;
$.each(movies, function(index, movie) {
$(document.body).append('<h1>' + movie.title + '</h1>');
$(document.body).append('<img src="' + movie.posters.thumbnail + '" />');
});
}
</script>
I have an API key, my question is how would I be able to create a form that would change out the value for var query = "Gone With The Wind"; as the user submitted an input search with a HTML form such as this:
<input id="search">
<input type="submit" value="Submit">
Also would this be able to lead to another HTML page once searched?
complete rewrite ...
You should wrap the supplied (and modified) code in a function which you can then call through an event binding, like a submit event on your input form.
Below you will find a complete and working example of how you could do it. I replaced the given URL with a publicly available one from spotify. As a consequence I had to modify the callback function a little bit and also the dataType paramater in the $.ajax() argument object was changed to 'json' (instead of originally: 'jsonp').
At the end of the lookformovie() function you will find return false;. This prevents the submit event from actually happening, so the user stays on the same page.
function lookformovie(ev){ // ev is supplied by the triggered event
console.log('go, look!');
// the following WOULD be important, if this function was triggered
// by a click on a form element and you wanted to avoid the event to
// "bubble up" to higher element layers like the form itself.
// In this particular example it is superfluous
ev.stopPropagation();
var apikey = "[apikey]";
var baseUrl = "http://api.rottentomatoes.com/api/public/v1.0";
// construct the uri with our apikey
var moviesSearchUrl = baseUrl + '/movies.json?apikey=' + apikey;
// --- start of spotify-fix ---
moviesSearchUrl="https://api.spotify.com/v1/search?type=track";
// --- end of spotify-fix -----
// the following gets the contents of your changed input field:
var query=$('#search').val();
$.ajax({
url: moviesSearchUrl + '&q=' + encodeURI(query),
dataType: "json", // spotify-fix, was: "jsonp"
success: searchCallback
});
return false; // this prevents the submit event from leaving or reloading the page!
}
// modified callback (spotify-fix!!):
function searchCallback(data){
console.log('callback here');
$('#out').html(data.tracks.items.map(
function(t){ return t.name;}).join('<br>\n'));
}
// original movie callback for Rotten Tomatoes:
function searchCallback_inactive(data) {var str='';
str+='Found ' + data.total + ' results.';
var movies = data.movies;
$.each(movies, function(index, movie) {
str+='<h1>' + movie.title + '</h1>';
str+='<img src="' + movie.posters.thumbnail + '" />';
});
$('#out').html(str);
}
$(function(){
$('form').on('submit',lookformovie);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input type="text" id="search" value="james brown">
<input type="submit" value="get tracks">
</form>
<div id="out"></div>
You might have noticed that I placed several console.log() statements at various places into the code. This helped me during debugging to see which part of the functionality actually worked, and where something got stuck. To see the output you need to have your developer console opened of course.
You can construct form, with input element named "q", then handle form submit event.
<form action="http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=API_KEY" method="get">
<input id="search" name="q">
<input type="submit" value="Submit">
</form>

Categories

Resources