I'm looking to put a div on my website where the content changes based on what link is clicked without refreshing. The content to put there comes from a MySQL database and it's put in JSON.
My problem is that I can't get the JSON data to display when clicking the links.
Here's the script I'm using:
$(document).ready(function () {
$.getJSON("jsondata.php",rightSideData);
function rightSideData(data) {
for(var i=0; i<data.length;i++) {
$("#changetext"+data[i].id).click(function() {
$("#rightside").html("<h1>" + data[i].title + "</h1><p />" + data[i].content);
});
}
}
});
This is the div element that has to change:
<div class='rightside' id='rightside'>Test</div>
The links are constructed this way:
echo "<a id='changetext" . $row['id'] . "'> ";
echo "<div class='tile'>";
echo "<h2>Tile</h2></div></a>";
I've tested the different elements and they work fine (changing the divs content with hardcoded data, displaying the JSON data), but I'm having a hard time figuring out why the combined thing isn't working.
Objects does'nt have a length, use $.each to iterate it instead, unless it's actually an array containing objects :
$(document).ready(function () {
$.getJSON("jsondata.php",rightSideData);
function rightSideData(data) {
$.each(data, function(i, d) {
$("#changetext" + d.id).on('click', function() {
var h1 = $('<h1 />', {text : d.title}),
p = $('<p />', {text : d.content});
$("#rightside").html(h1.add(p));
});
});
}
});
The problem is that i var will be data.length at the end of the loop and that's what the click handler will see.
Related
My algorithm:
I get the DIV text from php/SQL ($.get( "read.php"...)
APPEND contenteditable div with loaded text by jQuery
check the div value, if there is errors in text I make div red (assign class, $(this).addClass("fill_red");)
on every change of text - check and assign/remove class if needed.
Problem is: with preloaded text - everything is working.
But when I append div using JS - check function don't works.
I searched the web, maybe on() method helps me.
But what event?
It should be something like onload, onchange..?
(yes, I could make div generated by php and solve the problem, but I dont want full refresh)
Thank you!
part of code:
//texts load
$(function() {
$.get( "read.php", function( data ) {
var ionka = data.split(' ');
ionka.forEach(function(item, i, arr) {
var app_text = "<div id=\"segm" + i + "\" contenteditable role=\"textbox\">" + item + "</div>";
$("#textarea").append(app_text);
});
});
//checks
var intRegex = new RegExp('^[0-9/\]{5}$');
$('#textarea div').each(function(i,elem) {
if(!intRegex.test($(this).text())) {
$(this).addClass("fill_red");
}else{
$(this).removeClass();
}
});
// edit on change. Blur because of contenteditable
var segm_array = [];
$('#textarea div').each(function(i,elem) {
$(this).blur(function() {
if (segm_array[i]!=$(this).text()){
segm_array[i] = $(this).text();
if(!intRegex.test(segm_array[i])) {
$(this).addClass("fill_red");
}else{
$(this).removeClass();
}
}
});
});
You dont show much code here, but my guess is that you are trying to add class before new data is loaded into dom
$.get( "read.php" ).done(function( data ) {
// addClass etc
});
So, I've been learning PHP over the past year or so and recently been playing with Ajax and Jquery. The reason for this is that it seems inefficient to constantly fire PHP scripts off and reload my html each time I want to display or do something.
So what I'm doing: I have a html document with input fields which I need to populate with data. The data is retrieved via a Ajax post call to a PHP script and returns a Json_encoded string. Jquery uses the JSON object to iterate through.
Where I am: I have managed to have Ajax pull back the correct results and populate the input elements I require. The results should be displayed as dynamically named Div IDs as list elements for each. This kind of works but I'm probably over complicating the process.
What I have with this code: So the results come back, and as I start typing in the search box, multiple results will return in the fashion I like. The on(click...) event works to a degree - i.e. it does populate the fields BUT only the last returned result from the Ajax call (last item).
I think the code is almost there (although could be made less complex but it's out of my reach at my current level). It's probably my flow which is wrong (i.e. using .each and then using a click event within it ...) ... I've attempted multiple ways of re-arranging the code but cannot fathom it. Any advice would be amazing. Full code relating to this is attached.
HTML:`
<input type="text" id="search_js" autocomplete="off">
<!-- Show Results -->
<h4 id="results-text"> <b id="search-string"></b> </h4>
<div id="resultsdiv">
<ul id="results">
<!--Results should show up here with custom Div IDs to keep unique -->
</ul>
<!-- END resultsdiv -->
</div>
<!-- End search-container div -->
</div>
...`
PHP:
<?PHP
$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_POST['query']);
$search_string = "$search_string%";
if (strlen($search_string) >= 1 && $search_string !== ' ') {
// Build Query
$searchstmt = "select * from vw_person_full where name like :s;";
$database->query($searchstmt);
$database->bind(':s', $search_string);
//Custom PDO function - returns associative array
$result_array = $database->resultset();
$output = $result_array;
//convert result array into json format
$json_result = json_encode($output);
echo $json_result;
Jquery:
$(document).ready(function() {
$("input#search_js").on("keyup", function(e) {
// Set Timeout
clearTimeout($.data(this, 'timer'));
// Set Search String
var search_string = $(this).val();
// Do Search
if(search_string == '') {
$("ul#results").fadeOut();
$('h4#results-text').fadeOut();
} else {
$("ul#results").fadeIn();
$('h4#results-text').fadeIn();
$(this).data('timer', setTimeout(search, 100));
};
});
var newsearchres;
function search() {
var query_value = $('input#search_js').val();
var output = '';
//if search box is not empty :
if(query_value !== '') {
$.ajax({
type: "POST",
url: "search.php",
data: {
query: query_value
},
dataType: 'JSON',
cache: false,
success: function(searchres) {
$.each(searchres, function(i, val) {
var countval = i;
//searchres = JSON.parse(searchres);
newsearchres = searchres[i];
console.log(val+" " + countval);
//individual divs for results with ID=divres_##
//output += '<div data-val-index="countval"id="divres' + countval + '" class="cl_divres">';
output += '<div data-val-index="'+countval+'" id="divres' + countval + '" class="cl_divres">';
output += '<li>' + val.fighter_name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
console.log(searchres);
});
}
});
};
}
function showDetail(ref) {
var val_id = $(ref).attr('data-val-index');
var val = $.each(newsearchres, function(i, val2) {
if(i == val_id) return val2;
});
$("#pid").prop({
"value": val.pid
});
$("#firstname").prop({
"value": val.first_name
});
$("#lastname").prop({
"value": val.last_name
});
$("#fightername").prop({
"value": val.fighter_name
});
$("#addressl1").prop({
"value": val.address_line1
});
$("#addressl2").prop({
"value": val.address_line2
});
$("#town").prop({
"value": val.town
});
$("#city").prop({
"value": val.city
});
$("#county").prop({
"value": val.county
});
$("#postcode").prop({
"value": val.postcode
});
$("#dob").prop({
"value": val.dob
});
$("#nat").prop({
"value": val.nationality
});
$("#email").prop({
"value": val.email
});
$("#homephone").prop({
"value": val.home_phone
});
$("#mobilephone").prop({
"value": val.mobile_phone
});
};
// $(document).find("div[id^='divres_']").on('click', function() {
$(document).on('click', 'div[id^="divres"]', function() {
console.log(this);
console.log("clicked");
showDetail(this);
});
});
Really sorry for crappy image - but hopefully it makes sense.
First thing that comes to mind right now is that you are ending the search result div at each item. I am only inclined to this because I see you open a new div in the $.each but you close 2.
See below:
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>'; // <--- add this after the $.each?
The possible reason is that "You are accessing the val for each li events that is accesing outside the each iteration so getting the last values only ."
So try to get the values from index .something as below -
$.each(searchres, function (i, val) {
var countval = i;
//individual divs for results with ID=divres_##
output += '<div data-val-index="countval"
id="divres_' + countval + '" class="cl_divres">';
output += '<li>' + val.name + '</li>';
//end individual divs:
output += '</div>';
//End search result Div:
output += '</div>';
//Display output in the result div:
$('#resultsdiv').html(output);
$(document).find("div[id^='divres_']").on('click',function(){showDetail(this); });
});
Now your callback for event may be as -
function showDetail(ref)
{
var val_id=$(ref).attr('data-val-index');
var val=$.each(searchres, function (i, val2) { if(i==val_id) return val2 ;});
$("#pid").prop({"value": val.pid});
$("#firstname").prop({"value": val.first_name});
$("#lastname").prop({"value": val.last_name});
$("#fightername").prop({"value": val.name});
$("#addressl1").prop({"value": val.address_line1});
$("#addressl2").prop({"value": val.address_line2});
$("#town").prop({"value": val.town});
$("#city").prop({"value": val.city});
$("#county").prop({"value": val.county});
$("#postcode").prop({"value": val.postcode});
$("#dob").prop({"value": val.dob});
$("#nat").prop({"value": val.nationality});
$("#email").prop({"value": val.email});
$("#homephone").prop({"value": val.home_phone});
$("#mobilephone").prop({"value": val.mobile_phone});
}
I am dynamically adding list items to a list in jQuery through an ajax call that is called every second.
Below is the code for the ajax call.
$.ajax({
url: 'php/update_group_list.php',
data: '',
dataType: 'json',
success: function(data) {
var id = data.instructor_id;
group_cnt = data.group_cnt,
group_name = data.group_name,
group_code = data.group_code;
for (i = current_row; i < group_cnt; i++)
{
//setInterval(function() { $('#group-list-div').load('php/group_list.php'); }, 5000);
$('#group-list').append("<li><a href='#' data-role='button' class='view-group-btns' id='"+group_code[i]+"' value='"+id+"' text='"+group_name[i]+"'>"+group_name[i]+"</a></li>");
$('#delete-group-list').append("<fieldset data-role='controlgroup data-iconpos='right'>" +
"<input id='"+group_code[i]+i+"' value='"+group_code[i]+"' type='checkbox' name='groups[]'>" +
"<label for='"+group_code[i]+i+"'>"+group_name[i]+"</label>" +
"</fieldset>");
}
current_row = i;
$('#group-list').listview('refresh');
$('#delete-group-list').trigger('create');
}
});
Now I am having two problems
FIRST PROBLEM:
When I try to run the code below (it should show an alert box if any of the list items created in this line $('#group-list').blah...blah in the code above), nothing happens.
$(".view-group-btns").click(function()
{
alert("check");
});
SECOND PROBLEM:
Also when I try to send the form data for the checkboxes (referencing line $('#delete-group-list').blah...blah in the ajax call code above) the post returns the error unexpected token <
What am I doing wrong? I think the two problems are related as I am creating the list items that are used dynamically.
Here is extra code relating to the SECOND problem
HTML:
<form id='delete-group-form' action='php/delete_groups.php' method='post'>
<h3 style='text-align: center;'>Check the Box Beside the Groups you Would Like to Delete </h3>
<div style='margin-top: 20px;'></div>
<div id='delete-group-list'>
</div>
<div style='margin-top: 20px;'></div>
<input type='submit' id='delete-groups-btn' data-theme='b' value='Delete Groups(s)'>
</form>
JS Code
$('#delete-group-form').submit(function(e)
{
e.preventDefault();
alert($('#delete-group-form').serialize());
if ($('#delete-group-form').serialize() == "")
{
alert('No groups selected to be deleted.')
return false;
}
else
if ($('#delete-groups-form').serialize() == null)
{
alert('No groups selected to be deleted.')
return false;
}
else
{
$.post('php/delete_groups.php',$('#delete-groups-form').serialize()).done(function(data)
{
obj = jQuery.parseJSON(data);
var group_codes = obj.group_list;
alert(group_codes);
alert("The selected groups have been deleted");
window.setTimeout(2000);
return false;
});
}
return false;
});
delete_groups.php
<?php
$group_codes = $_POST['groups'];
$items = array('group_list'=>$group_codes); //creating an array of data to be sent back to js file
echo json_encode($items); //sending data back through json encoding
?>
I think the root of the SECOND problem is the line $group_codes = $_POST['groups']; specfically the $_POST['groups'] because when I replace it with $group_codes = 'test'; (just for debugging purposes) , the code works as expected.
You need to use event delegation to make your newly-created elements function properly:
$("#group-list").on("click", ".view-group-btns", function() {
alert("check");
});
I noticed you have 3 single quotes on this line... missed one after controlgroup
$('#delete-group-list')."<fieldset data-role='controlgroup data-iconpos='right'>"
That would explain the unexpected token <
You have to use the jquery on event.
$(".view-group-btns").on("click", function(event)
{
alert("check");
});
Why?
Because you can only use the regular "click" on elements that are created BEFORE the DOM is updated.
When you are dynamically creating new elements into the dom tree, then you can't use .click anymore.
on (and in the past, .live(), which is deprecated now) can listen to modifications in the DOM tree and can use the later-on created elements.
You have to bind the click function after you get the element from ajax call. Binding on pageLoad event will only bind with those elements that are already in the dom. So do something like this.
$.ajax({
success : function(res){
//bind your click function after you update your html dom.
}
})
I'm attempting to take the ImageResolver plugin and adapt it to work with a php array.
Stripping the code to this returns the image without a form:
$(function(){
var url = $('#url').val();
ImageResolver.resolve(url, function(image){
if (image) {
$('#result').html('<img src="' + image + '" alt="">');
} else {
$('#result').html('<h2>No image found</h2>');
}
});
});
I want to adapt it to work within a php foreach loop. results would be replaced on the next class='result' div. IE: after the page has loaded the urls from the query, the function will parse the url and return image link if one is found. I'm guessing I need to use (each) or this(), but I can't figure it out.
can someone point me in the right direction?
<script src="ImageResolver/URI.min.js"></script>
<script src="ImageResolver/ImageResolver.js"></script>
<?
$javascriptarray = 'var urls = [';
$counter=0;
foreach (array('http://www.apple.com/','http://github.com/','http://www.test.com/') as $url)
{
if ($counter++ > 0) $javascriptarray .= ',';
$javascriptarray .= '"'.$url.'"';
}
$javascriptarray .= '];';
?>
<script>
<?=$javascriptarray?>
//The ImageResolver will try all the resolvers one after the other
//in the order of their registration
//Resolvers that guess the image URL
ImageResolver.register(new FileExtensionResolver());
ImageResolver.register(new ImgurPageResolver());
ImageResolver.register(new NineGagResolver());
ImageResolver.register(new InstagramResolver());
//Resolvers that need extra ajax requests
ImageResolver.register(new ImgurAlbumResolver());
ImageResolver.register(new OpengraphResolver());
ImageResolver.register(new WebpageResolver());
//Some jQuery code to make the demo work
//Use a crossdomain proxy (required by some plugins)
$.ajaxPrefilter('text', function(options) {
options.url = "http://furious-stream-4406.herokuapp.com?src=" + encodeURIComponent(options.url);
});
$(function(){
var length = urls.length,
url = null;
for (var i = 0; i < length; i++) {
url = urls[i];
ImageResolver.resolve(url, function(image){
if (image) {
$('#result').append('<img src="' + image + '" alt=""><br>');
} else {
$('#result').append('<h2>No image</h2>');
//$('#result').append('<h2>No image found for ' + url + '</h2>');
}
});
}
});
</script>
Watch out cause ImageResolver.resolve() works asynchrone you can get unexpected results. Call ImageResolver.resolve() again before the previous call has finished will change url in $('#result').append('<h2>No image found for ' + url + '</h2>'); to the url of your last call by example. To prevent this you need to initialize a new Resolver in the for-loop. see: Javascript prototypes and instance creation
After so many trials, I have finally managed to create pages dynamically using PHP, JSON and AJAX and load them into DOM. But the problem now is I'm unable to call/navigate those pages dynamically, but manually i.e gallery.html#page1 ...etc.
I seek guidance rather than burdening you, as I'm here to learn.
**PHP - photos.php **
$photos = array();
$i=0;
while ($row = mysqli_fetch_array($query)){
$img = $row["fn"];
$photos[] = $img;
$i++;
}
$count = count($photos);
echo json_encode(array('status' => 'success', 'count' => $count, 'items' => $photos));
JSON array
{
"status":"success",
"count":3,
"items":
[
"img1.jpg",
"img2.jpg",
"img3.jpg"
]
}
I use the below method to fetch and store ID of the desired gallery,
<input type="hidden" value="<?php echo $id; ?>" id="displayid" />
and then I call it back to use it in AJAX.
var ID = $('#displayid').val();
AJAX and JQM
$.ajax({
Type: "GET",
url: 'photos.php',
data: { display: ID }, // = $('#displayid').val();
dataType: "json",
contentType: "application/json",
success: function(data) {
var count = data.count;
var number = 0;
$.each(data.items, function(i,item) {
var newPage = $("<div data-role=page data-url=page" + number + "><div data-role=header><h1>Photo " + number + "</h1></div><div data-role=content><img src=" + item + " /></div></div");
newPage.appendTo( $.mobile.pageContainer );
number++;
if (number == count) { $.mobile.changePage( newPage ); }; // it goes to last page
I got this code from here thanks Gajotres to dynamically navigate between pages. It's within the same code.
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
}); // next button
}); // each loop
} // success
}); //ajax
I found your problem.
This part of code can't be used here like this:
$(document).on('pagebeforeshow', '[data-role="page"]', function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$.mobile.activePage.find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'b'}).addClass('ui-btn-right').html('Next').button());
}
});
This is the problem. First remove pagebeforeshow event binding, it can't be used here like that. Rest of the code is not going to do anything because currently there are any next page (next page is going to be generated during then next loop iteration), so remove this whole block.
Now, after the each block ends and all pages are generated (that is the main thing, all pages should exist at this point), add this code:
$('[data-role="page"]').each(function(){
var nextpage = $(this).next('div[data-role="page"]');
if (nextpage.length > 0) {
$(this).find('[data-role="header"]').append($('<a>').attr({'href':'#'+nextpage.attr('id'),'data-theme':'a'}).addClass('ui-btn-right').html('Next').button());
}
});
This is what will happen. Each loop will loop through every available page (we have them all by now) and in case it is not the last one it will add next button.
Here's a live example: http://jsfiddle.net/Gajotres/Xjkvq/
Ok in this example pages are already there, but point is the same. They need to exist (no matter if you add them dynamically or if they are preexisting) before you can add next buttons.
I hope this helps.