I have a table that when a row is clicked it sends the first 6 characters of that row (an ID) to a PHP page and loads the subsequent data into a div further down the page. The issue it seems is that once I click a row to load the div, The majority of the jQuery events stop working (.hover, .sortElements) these are attached to the original table. Is there anyone that would know a 'fix' or work around for this issue or is there something I am just missing.
<SCRIPT type='text/javascript'>
$(document).ready(function(){
$(".panel").hide();
$(".itemjobbutton").click(function(){
$(".panel").slideToggle("200");
return false;
});
var inverse = false;
$("#jobTable th").click(function(){
var header = $(this),
index = header.index();
header
.closest('table')
.find('td')
.filter(function(){
return $(this).index() === index;
})
.sortElements(function(a, b){
a = $(a).text();
b = $(b).text();
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
}, function(){
return this.parentNode;
});
inverse = !inverse;
});
$('#jobTable tr').click(function(){
if($(this).index() != 0) {
var thistext = $(this).text().substring(0,6);
$("#joblistingDetail").load('jobview.php' , {jobID: thistext}).hide().slideDown('100');
$("#jobTable tr").css("background", "#fff");
$(this).closest('tr').css('background-color', '#C3D9FF');
}
});
});
$('#jobTable tr').hover(
function() {
$(this).addClass('hover');
},
function() {
$(this).removeClass('hover')
}
);
Your jobview.php is more than likely including it's own version of jquery.js that is overriding the one on the parent page. Either remove it from jobview.php, or modify your .load to only pull in html from within a given selector such as
$("#joblistingDetail").load('jobview.php #target')
where #target is a selector selecting a specific container to pull in.
Related
I am working on a project that is almost done in my office, there are several pages that use plug-in datatable and use accordion, in this case the problem is that the searchbox I created is irregular. how to fix this?
Datatables Display so far
All processes are normal, but my production manager has asked to change the position of the searchbox to the right
here my Datatables code :
$current_script = '
$(".accordion-toggle").on("click", function () {
var table_key = $(this).data("index");
var table_tbody = $("#asset-"+table_key+" tbody");
console.log(table_tbody);
if(table_tbody[0].childElementCount == 0){
var table_aset = $("#asset-"+table_key).dataTable({
"pagingType":"simple_numbers",
"searching": true,
"AutoWidth":true,
"scrollY": "400px",
"ajax":{"url":"'.site_url($this->current_page.'/get/?get=1&lokasi=').'"+table_key,
"type":"post"}
});
//table_aset.ajax.url("'.site_url($this->current_page.'/get/?get=1&lokasi=').'"+table_key).load();
$.get("'.site_url($this->current_page.'/get/').'",{
get : 2,
lokasi : table_key
},
function(data){
$(".tot_perolehan-"+table_key).html(data.total_perolehan);
},"json");
}
});
';
(simplified) Scenario: a remote MySql DB and an HTML page with 2 buttons: SHOW and SELECT. The SHOW loads a single record and displays the fields in a form.
Everything is ok on this side.
The SELECT was made with a new approach for me:
I pass a parameter to a PHP function to query the DB and create an html file with the resuls.
This file is a series of <UL><LI><a id="1"...data..</LI></UL> to be inserted within a DIV.
One of the <LI> contains a link that, when clicked, calls the SHOW function. The record identification is made by mean of the ID associated to the anchor.
This procedure works fine; I get the new HTML segment (that I can check on the remote web server).
It is inserted (???) inside my DIV and the content is correctly displayed on screen, but... it does not exist.
Clicking on the links does not activate the SHOW procedure (actually, an Alert with the calling ID is never shown).
Looking to the html page source from Mozilla it still shows the previous content, without the new added (or replaced) code.
This is the reason for this post's title: I see something that really is not there.
Possibly, I should have AJAX to 'refresh' its visibility of the DOM, but and do not understand how.
This is the piece of JQuery script that I use to get the new content:
$("#select").click(function() {
$.ajax({
url: "new_record_list.php",
cache: false,
success:
function(recNumber)
{
$("#selected").val(recNumber); //ok
$("#recordList").load("list.txt"); //'list.txt is created by new_record_list.php
alert($("#recordList").html()); //this is OK
}
});
});
Everything is ok, but where is the meat?
Most likely the listener you created did not attach to the new dom nodes.
You can fix this by attaching a listener to a parent element that exists at page creation or even the document like so:
$(document).on('click', '.show', function() {
//click event
});
Replace ".show" with the jquery selector for the links
Since I'm unable to comment on your new post due to rep:
Remove the click event handler inside the loadRecord function.
The click event was already bound at the top of your script. What happens is that you click, activate the load record function which binds a new click handler, triggering the action on all the clicks following it.
The load record should look like this instead:
function loadRecord(){
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
};
Also, you should replace
$(document).on('click', '.compLink', function() {
loadRecord();
});
with
$(document).on('click', '.compLink', loadRecord);
And loadRecord will be passed the mouse event as an argument. $(this) will also refer to the link you clicked inside the loadrecord function.
Otherwise you need to pass the element clicked into that function.
One issue I can see straight away is the AJAX call, it should be along the lines of:
$( "#select" ).on( "click", function ()
{
$.ajax( {
url: "new_record_list.php?record=MY_RECORD_VALUE",
type: "GET",
success: function ( response )
{
$( "#selected" ).val( response );
$( "#recordList" ).html( function ()
{
$.ajax( {
url: "list.txt",
typ: "GET",
success: function ( response2 )
{
$( "#recordList" ).html( response2 );
}
} );
} );
alert( $( "#recordList" ).val() );
},
beforeSend: function()
{
$( "#recordlist" ).html( "Loading..." );
$( "#selected" ).val( "Loading..." );
}
} );
} );
This will give a better result from the $.ajax call that you have made.
The .load() method can be quite unreliable at times, hence why it is (IMO) better to make an ajax within an ajax, because that's what your doing with less control effectively.
Where you have done the function(recNumber) is kinda wrong I'm afraid, whats brought back from the AJAX call is the response, everything that would be shown should you be using it as an actual page, e.g. if you had:
<table>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
</table>
<input id="id_valued" value="2" />
Then this whole thing would be returned, not just the id_valued input field.
I followed the hints from Erin plus some other suggestion found on this forum and now the program ALMOST works.
Actually it does, but when a new set of records is loaded, to update the display (that is to call the loadRecord function) it is necessary to click twice on a link, the very first time only. All next clicks reacts immediately.
I try to post the entire script, for you experts to see what I hardly did:
<script type="text/javascript">
$(document).ready(function()
{
$(document).foundation();
var $scrollbar = $("#scrollbar1"); //other stuff
$scrollbar.tinyscrollbar();
//Erin suggestion + my understanding
$(document).on('click', '.compLink', function() {
loadRecord();
});
/* =========== ADD Rows ============================== */
/* action called by hitting the "selectRow" button.
/* query the DB and get a list of rows (5 fields each)
/* that are then inserted into the '#recordList' DIV.
/* Each rows has format:
/* <UL><LI><A id="xxx" class="compLink" ...>item xxx</A></LI><LI>....</LI></UL>
*/
$("#selectRow").on( "click",function()
{
$.ajax(
{
url: "new_record_list.php",
type: "GET",
success: function(recNumber) //if ok, we get the number of records
{
$("#selectedRecords").val(recNumber); //show how many records we got
$("#recordList").load("newRecords.txt"); //loads the remote text file into the DIV
}
});
});
/* ====================================================== */
/* =========== LOAD Record ============================== */
/* loads and displays an entire record from DB,
/* based on the ID of clicked link with class="compLink"
/* in '#recordList' DIV.
/* Example: <a id="1" class="compLink" ...>
*/
function loadRecord(){
$(".compLink").click(function(event)
{
ind = $(this).attr("id");
$("#thisRecord").val(ind); //shows the clicked record
$.get("show_record.php",{id:ind}, function(gotString)
{
ptr=0; //used to fetch fields
pos=0;
lun = gotString.length;
if (lun==0) {
alert ("Empty string!");
return false;
};
// fetch received keys and values then fills the fields
while (ptr < lun) {
..... //not interesting here
}; //while
});
return false; //required!
});
};
/* ====================================================== */
return false;
});
</script>
I hope this is clear enough. Thanks
I have a function that loads images within a gallery.
Throughout the site it loads the last 20 images, then when a user scrolls down it loads another 20 and works with an infinite scroll code.
However, on one page this does not work and I'm baffled as to why not.
I've narrowed down the problem code to this:
function getEachBoardPins($id,$limit=false)
{
$sql = "SELECT
*
FROM
pins
WHERE
board_id = $id
ORDER BY time DESC";
if($limit)
$sql .=" LIMIT $limit" ;
$query = $this->db->query($sql);
return $query->result();
}
This will load EVERY image within the gallery. Some galleries have in excess of 1000 images so it takes an eternity to load.
By changing the "$limit=false" value to true in the first line only renders the last uploaded image.
Can anyone help me or point me in a kind direction so I can solve it?
thanks.
EDIT:
Infinite scroll code:
$(function(){
// alert($('.pin_item').length);
var $alpha = $('#alpha');
$alpha.imagesLoaded( function(){
$alpha.masonry({
itemSelector: '.pin_item',
isFitWidth: true,
isAnimatedFromBottom: true
//isAnimated: true
});
});
$alpha.infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector : '.pin_item', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: '<?php echo site_url(); ?>/application/assets/images/ajax_loader_blue.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$alpha.masonry( 'appended', $newElems, true );
$("a.act_uncomment").hide();
$(".enter_comm").hide();
//Examples of how to assign the ColorBox event to elements
$(".group1").colorbox({rel:'group1'});
$(".group2").colorbox({rel:'group2', transition:"fade"});
$(".group3").colorbox({rel:'group3', transition:"none", width:"75%", height:"75%"});
$(".group4").colorbox({rel:'group4', slideshow:true});
$(".ajax").colorbox({scrolling:false,transition:"elastic"});
$(".youtube").colorbox({iframe:true, innerWidth:425, innerHeight:344});
$(".iframe").colorbox({iframe:true, width:"80%", height:"80%"});
$(".inline").colorbox({inline:true, width:"50%"});
$(".callbacks").colorbox({
onOpen:function(){ alert('onOpen: colorbox is about to open'); },
onLoad:function(){ alert('onLoad: colorbox has started to load the targeted content'); },
onComplete:function(){ alert('onComplete: colorbox has displayed the loaded content'); },
onCleanup:function(){ alert('onCleanup: colorbox has begun the close process'); },
onClosed:function(){ alert('onClosed: colorbox has completely closed'); }
});
//Example of preserving a JavaScript event for inline calls.
$("#click").click(function(){
$('#click').css({"background-color":"#f00", "color":"#fff", "cursor":"inherit"}).text("Open this window again and this message will still be here.");
return false;
});
});
}
);
});
from all of mysql experience limit should be set to an integer and thus will only return a maximum of that many results. try that out with adding a numeric limit to that query
The way you're doing it, whatever number you pass in will only return the last $limit number of records. If you're querying for more images, you're going to return all the records you already retrieved PLUS the additional records (if you're just increasing that number, for example).
Also, instead of passing $limit in as a boolean / integer (mixing data types isn't good practice), maybe you should pass it as a number. For example:
function getEachBoardPins($id, $start=0, $numrows=20)
{
$sql = "SELECT *
FROM pins
WHERE board_id = {$id}
ORDER BY time DESC
LIMIT {$start},{$numrows}
";
$query = $this->db->query($sql);
return $query->result();
}
I'm making the assumption you're sanitizing your variables before passing them to your function.
Another way to do it would be to pass in the ID of the last record retrieved. That way, you can pick up exactly where you left off in case new images have been added since the last time the data was refreshed.
I am working on a site right now and have discovered that the jquery/javascript that I have implemented for the Search applies the same effect to all search boxes on the page when I click in the input field. By default, it removes the "Search" text and clears it out so that you can type your search term. I only want it to perform this function on the search box that is clicked within, not all search boxes on the page. However, if you look at this example, you'll notice that when you click into the search field at the top of the page, it clears the text out of both. I think I could fix it with .parent() or something, but am a jQuery novice. Any help would be appreciated.
Also don't know quite why the border is showing up around my icon, but I'll fix that.
Here's the search function jQuery:
$(document).ready(function(){
$('.search-box').textdefault({'text':'Search'});
});
(function($){
$.fn.textdefault = function(settings){
var Elements = this;
var settings = $.extend({}, $.fn.textdefault.defaults, settings);
return Elements.each(function(){
if($(Elements).is("input")){ TextDefault( $(Elements) ); }
});
function TextDefault(Input){
if (Input.val().length==0) Input.val(settings.text);
Input.focus(function () {
if (Input.val()==settings.text) Input.val('');
});
Input.blur(function () {
if (Input.val().length==0) Input.val(settings.text);
});
}
};
$.fn.textdefault.defaults = {
text: 'Search'
};
})(jQuery);
Thanks!
Taylor
plugin example
here is the correction.
Elements contains all the elements that are 'passed' to this plugin.
var Elements = this;
By using $(Elements) instead of $(this) in the each function, you
used all inputs as one
return Elements.each(function() {
if ($(this).is("input")) {
TextDefault($(this));
}
});
This line of code should be called to initialize the plugin. So it should be put somewhere outside of the plugin, in a $(document).ready() {} code block for example, since you need the plugin initialized for the inputs on the load of the page.
$('.search-box').textdefault({
'text': 'Search'
});
Use a different selector. Instead of all inputs with a class of "search-box" try giving it a unique ID or class.
$("#search_default").textdefault({'text':'Search'});
or
$(".search-box.defaulttext").textdefault({'text':'Search'});
The HTML would then be
<input type="text" class="search-box defaulttext" ...
or
<input type="text" id="search_default" ...
This is the method that I use, which could also be helpful for you. It won't fire for both objects since it uses $(this) to control just the object being focused/blurred.
$(".search-box").live("focus", function(){
if ( $(this).val() == $(this).attr("rel") ){
$(this).val('');
}
}).live("blur", function(){
if ( $(this).val() == '' ) {
$(this).val( $(this).attr("rel") );
}
}).each( function(){
$(this).attr("rel", $(this).val() );
});
I would try to use a more "jQuery" way to do this. jsFiddle
$('input').focus(function(){
$(this).data('text', $(this).val()).val('');
});
$('input').blur(function(){
if( $(this).val() === "" ) $(this).val( $(this).data('text') );
});
How can I hide and show a div (and change the width of another div) using the same link,for example I can show A div and change its widht. How can I make it so that if the user clicks again, the width goes back to 600px and the right div is hidden.
$("a").click(function(event){
$('#main-content').width(800);
$('#right').show('slow').slideDown('slow');
event.preventDefault();
});
EDIT:
From All your replies, I've done this:
$(document).ready(function(){
$('#right').hide();
$('#main-content').width(600);
$('#show-stats').toggle(function() {
$('#main-content').width(800);
$(this).text($(this).text() == 'Show' ? 'Hide' : 'Show');
$('#right').show('slow').slideDown('slow').fadeIn('slow');
event.preventDefault();
}, function() {
$('#main-content').width(600);
$(this).text($(this).text() == 'Hide' ? 'Show' : 'Hide');
$('#right').hide('slow').slideUp('slow').fadeOut('slow'); // change the text
event.preventDefault();
});
});
Will this break the internet? Is there a more elegant way or is this fine?
You can use .toggle()
A small example :
$("a").toggle(
function() {
$('#main-content').width(800);
$('#right').show('slow').slidedown('slow');
},
function() {
$('#main-content').width(600);
$('#right').hide();
}
);
You need to use the toggle pseudo-event handler. This accepts multiple function definitions as its arguments and calls them in turn, so, given two arguments, the first call will call the first function, the second call the second function, the third call the first function, etc...
$('a').toggle(function(event){
$('#main-content').width(800);
$('#right').show('slow').slideDown('slow');
event.preventDefault();
}, function(event) {
$('#main-content').width(600);
$('#right').slideUp('slow').hide('slow');
event.preventDefault();
});