I have a page with 2 Div containers ( Left and Right ).
PartsList page has 5 dynamically generated DIVS.
Custom page has 5 dynamically generated DIVS.
The div with id "layout" isnt getting recognized with the jQuery .on(). Please help. Thank you for you time :).
<script type="text/javascript" src="js/jquery.js">
</script>
<script type="text/javascript">
$(function() {
$(".left").load("PartsList.php",function() {alert("success");});
$(".right").load("Custom.php", function() {alert("success");});
$("#layout").children().on({click: function() {
alert($(this).attr('id'));
}
});
});
</script>
<body>
<div class="main">
<div class="left">
//Load Left page.
</div>
<div class="right">
//Load Structure page.
</div>
</div>
</body>
</html>
PartsList
<?php
for ($x = 1; $x < 6; $x++)
{
$divs = <<<here
<div id = 'div$x' class = 'list'><strong>Div: $x</strong></div>
here;
echo $divs;
}
?>
Custom
<?php
echo '<div id="layout">';
for ($y = 0; $y < 5; $y++)
{
echo "<div id='x$y' style='
position: absolute;
width: 200px;
height: 100px;
top: ".(100 * $y)."px;
border: 2px solid blue;
cursor: pointer;
'></div>";
}
echo '</div>';
?>
in jquery 1.7+ use on like
$(document).on('click','dynamicElement',function(e){
//handler code here
});
in the earlier versions use delegate
$(document).delegate('dynamicElement','click',function(e){
//handler code here
});
you can replace the document with parent element of the dynamically generated element
From the Jquery online manual:
.load( url [, data] [, complete(responseText, textStatus, XMLHttpRequest)] )
url: string containing the URL to which the request is sent.
data: map or string that is sent to the server with the request.
complete(responseText, textStatus, XMLHttpRequest)A callback function that is executed when the request completes.
You probably need to put the .on function as a callback of the .load for that Custom.php page.
Something like this EXAMPLE:
$(function() {
$(".left").load("PartsList.php",function() {alert("success");});
$(".right").load("Custom.php", function() {alert("success");
$("#layout").children().on({click: function() {
alert($(this).attr('id'));
}
});
});
});
I think you've got the wrong syntax for the .on() function it should be something like:
$('document').on('click', '#layout > div', function() {
alert($(this).attr('id'));
});
You bind to the document and when a user clicks on a child div in layout the event 'bubbles' up the DOM to the document where it is caught.
Okay. I found the answer anyhow. For people who were thinking why it didnt work. It was because of the stupid QUOTES.
$("document") should have been $(document) since document isnt a tag <.
And tada thats it.
Sigh.
Thanks for the help everyone :)
Related
I was trying to parse data to my controller so I can insert it into the database using JQuery and it was returning null. It's for a review star system so doesn't use conventional form fields however the network tab in inspect elements shows that data is actually posted to the controller just, not able to read it for some weird reason.
Update: The data is being inserted fine on desktop however the confirmation (flashdata) message is shown correctly not sure why. Additionally on mobile view no data or message is shown. Does anyone know why? I have updated the code below..
Here's the code from my view:
<?php if($this->session->flashdata('review_submitted')){ ?>
<div class="alert alert-success alert-dismissible container show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>Thank you!</strong> Your review has been submitted.
</div>
<?php } ?>
<form id="myForm" name="myForm">
<br>
<div class="form-group text-left div-style">
<h3 style="font-family: MontserratLight;letter-spacing: 2px; line-height: 32px;">Full Name <b>*</b></h3>
<input name="name" class="form-control" style="background: #f7f7f7; border: 1px solid #801424;" required />
</div>
<div class="rate">
<div id="1" class="btn-1 rate-btn"></div>
<div id="2" class="btn-2 rate-btn"></div>
<div id="3" class="btn-3 rate-btn"></div>
<div id="4" class="btn-4 rate-btn"></div>
<div id="5" class="btn-5 rate-btn"></div>
</div>
<script>
$(function(){
$('.rate-btn').hover(function(){
$('.rate-btn').removeClass('rate-btn-hover');
var therate = $(this).attr('id');
for (var i = therate; i >= 0; i--) {
$('.btn-'+i).addClass('rate-btn-hover');
};
});
$('.rate-btn').click(function(){
var therate = $(this).attr('id');
var dataRate = 'rate='+therate; //
$('.rate-btn').removeClass('rate-btn-active');
for (var i = therate; i >= 0; i--) {
$('.btn-'+i).addClass('rate-btn-active');
};
$('#myForm').on('submit', function(e){
var url = "<?php echo base_url(); ?>index.php/reviews/add_review";
// $('#myForm').append(therate);
var dataPost = $('#myForm').serialize() + "&rate=" + therate;
$.ajax({
type : "POST",
url : url,
data: dataPost,
success:function(){
}
});
});
});
});
</script>
and using the controller I simply use the following to get the data and add it to the database:
public function add_review(){
$name = $this->input->post('name');
$rating = $this->input->post('rate');
$dataDB = array(
'full_name' => $name,
'rating' => $rating
);
if($this->functions->submit($dataDB)){
$this->session->set_flashdata('review_submitted', true);
redirect(base_url() . 'reviews/index', 'refresh');
}
}
Here's some CSS that I used, perhaps the problem is to do with the mobile browser not having a cursor?
.rate{
width:245px; height: 40px;
margin-bottom:0px;
}
.rate .rate-btn{
width: 45px; height:40px;
float: left;
background: url(rate-btn.png) no-repeat;
cursor: pointer;
cursor:hand;
pointer-events: auto;
}
.rate .rate-btn:hover, .rate .rate-btn-hover, .rate .rate-btn-active{
background: url(rate-btn-hover.png) no-repeat;
}
When passing data through ajax, I think it is better to use JSON dataType. Reform the data type (string -> data object). Besides, I don't think it is really necessary to concat the 'to-be-sent' data into a string.
If you want dynamic data to be sent, you can push elements by condition
$.ajax({
type : "POST",
dataType: 'text' //it is not necessary if you are not returning any data (if you return json, put 'JSON'),
url : "<?php echo base_url(); ?>index.php/reviews/add_review",
data: dataRate, //change to {key:value,key:value}
success:function(data){
}
});
This is just to address your issue with your AJAX Posted Values not appearing where you are expecting them ONLY.
There are a zillion ways you can code this but here is just one which I have changed about to perform debugging. Even I learned a new trick doing this.
Just Nit Picking but what stuck out when reading your code is your use of therate when everywhere else in your JS you use camel case so it should be theRate.It's a good idea to choose a standard and stick to it.
Plus you had what appeared to be nested events in your JS. Some attempt at getting theRate to work correctly? Anyway...
First things. Get back to something basic and work your way back up. (Although in this case I didn't strip your view back to bare bones, but I did with your controller.
Your View.
I had to change this up a bit and hopefully the comments explain things.
I called it rating_view.php
<form name="my-form" id="my-form">
<div class="rate">
<div id="1" class="btn-1 rate-btn">1</div>
<div id="2" class="btn-2 rate-btn">2</div>
<div id="3" class="btn-3 rate-btn">3</div>
<div id="4" class="btn-4 rate-btn">4</div>
<div id="5" class="btn-5 rate-btn">5</div>
</div>
<input type="submit">
</form>
<!-- Added for viewing debug response -->
<div id="json-debug-output"></div>
<!-- Some styles added as non were provided -->
<style>
.rate-btn-hover {
background: blue;
}
.rate-btn-active {
background: yellow;
}
</style>
<script src= <?= base_url('assets/js/jquery_v3.4.1.js'); ?>></script>
<script>
$(document).ready(function () {
// Define your Dom Elements ONCE for efficiency etc
let domRateButton = $('.rate-btn');
let domMyForm = $('#my-form');
let theRate = 0; // Declares this as a Global Var.
let domJsonDebugOutput = $('#json-debug-output');
// Hover
domRateButton.hover(function () {
domRateButton.removeClass('rate-btn-hover');
let theRate = $(this).attr('id');
for (let i = theRate; i >= 0; i--) {
$('.btn-' + i).addClass('rate-btn-hover');
}
});
// Click
domRateButton.click(function () {
console.log('Rating Button Clicked');
theRate = $(this).attr('id');
domRateButton.removeClass('rate-btn-active');
for (let i = theRate; i >= 0; i--) {
$('.btn-' + i).addClass('rate-btn-active');
}
});
// Submit
domMyForm.on('submit', function (e) {
e.preventDefault(); // This was missing
console.log('Posting Rate = ' + theRate);
$.ajax({
type: "POST",
// dataType: 'text',
dataType: "json",
url: "<?php echo base_url(); ?>reviews/add_review",
data: {'act': 'rate', 'post_id':<?= $post_id; ?>, 'rate': theRate},
success: function (data) {
let debugData = JSON.stringify(data);
domJsonDebugOutput.text(debugData); // Display in our Debug Div
},
error: function (data) {
let debugData = JSON.stringify(data);
domJsonDebugOutput.text(debugData); // Display in our Debug Div
}
});
});
});
</script>
Note in the AJAX the changes to dataType from text to json. Also note that data is an array.
I also changed the scope of theRate from local to a global so it was "findable" amongst the functions.
NOT SURE how your form was setup but I added e.preventDefault(); to prevent the form submitting for testing.
Personally I cringe at having PHP vars embedded in any JS code and I usually have my JS as external files and pass in the values from PHP by reading them using JS but that's got it's Pros and Cons as well. So I left that alone for the sake of not going too far with this.
For your Controller - Called Reviews.php
public function show() {
$data['post_id'] = 1; // This comes from somewhere
$content = $this->load->view('rating_view', $data, TRUE);
echo $content;
}
/**
* Called by AJAX
* Do we need to test this is only called by AJAX?
*/
public function add_review() {
// Return everything that was sent for debugging
echo json_encode($this->input->post());
// var_dump($this->input->post());
exit();
}
So here I just had a method show() show the form and the add_review to simply bounce back what was sent. You can do all sorts of things with this. One nice aspect in this case is you do not need to use console.log) as you can view it all on the page (BUT ONLY FOR DEBUGGING). It's another option.
So have a play with that and start making changes to your code and see what works. Remember - get back to basics and pick on the bit that isn't working.
Next you will find you might be getting tripped up on your redirect. But that's for another post.
hai iam trying to place hover in an dynamic image have to show a dynamic div, if remove mouse div has to be hidden, if i over to the div after hover on image div needs to remain visible if i move out from the div it has to be hidden i tried something like this, but not working as expected, If i over to image div appears if i place mouseout tag there it hides the div once i remove the mouse couldn't use the options in the div, if i place the mouse out in div once i remove the mouse from image the div not closing, sorry for bad english as solutions for this case?
<img onmouseover="GoView_respond(<?php echo $print->Friend_id;?>);" onmouseout="ExitView_respond_one(<?php echo $print->Friend_id;?>);">
<div class="respond_request" style="display:none;" id="pending_req_<?php echo $print->Friend_id;?>" >
<p class="user_details" onmouseout="ExitView_respond(<?php echo $print->Friend_id;?>);">
</div>
<script>
function GoView_respond(id){
console.log('hovering');
document.getElementById("pending_req_"+id).style.display="block";
}
var cl=0;
function ExitView_respond(id){
console.log('not hovering');
if(cl!=1){
document.getElementById("pending_req_"+id).style.display="none";
}
}
</script>
Well, there are various ways to achieve this.
You could for example trick by setting a little timeout that will allow the mouse to reach the user details html node and vice-versa.
Let me be more explicit, according to your case
<?php
class Friend
{
public $Friend_id;
public $Friend_details;
public $Friend_image;
public function __construct($id, $details, $image){
$this->Friend_id = $id;
$this->Friend_details = $details;
$this->Friend_image = $image;
}
}
$print = new Friend(1, 'The very first user', 'http://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
?>
<img class="user_image" id="user_image_<?php echo $print->Friend_id; ?>" src="<?php echo $print->Friend_image; ?>" alt="some image" />
<div class="user_details" id="user_details_<?php echo $print->Friend_id; ?>">
<h5>User details</h5>
<?php echo $print->Friend_details; ?>
</div>
<style>
.user_details {
display: none;
background-color: lightgray;
width: 250px;
padding: 15px;
}
</style>
<script>
var userImages = document.getElementsByClassName('user_image');
for(var i = 0; i < userImages.length; i++){
var
userImage = userImages[i],
userId = userImage.id.replace('user_image_', ''),
thisUserDetails = document.getElementById('user_details_' + userId),
mouseOutTimeout = 100, // Here is the trick
mouseTimer = null; // Needed in order to hide the details after that little timeout
userImage.addEventListener('mouseout', function(){
mouseTimer = setTimeout(function(){
thisUserDetails.style.display = 'none';
}, mouseOutTimeout);
});
userImage.addEventListener('mouseover', function(){
clearTimeout(mouseTimer);
thisUserDetails.style.display = 'block';
});
thisUserDetails.addEventListener('mouseout', function(){
var _this = this;
mouseTimer = setTimeout(function(){
_this.style.display = 'none';
}, mouseOutTimeout);
});
thisUserDetails.addEventListener('mouseover', function(){
clearTimeout(mouseTimer);
});
}
</script>
Note: I've used getElementsByClassName and addEventListener here, that are not compatible with IE8 and earlier. Check this link for getElementsByClassName compatibility and this one for addEventListener.
Hope it help.
My question is very simple. I want to display only the content of one tr at a time. That means when I click on the other tr then the other opened tr should get closed.
My code is as below
<head>
<style>
p { width:400px; }
.click{cursor:pointer;}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
function visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'none')
e.style.display = 'block';
else
e.style.display = 'none';
}
</script>
</head>
Above is the head section where onClick a function called visibility is getting called. Below in the body section I am trying to display two tr using for loop.
<body>
<table>
<?php
$i=2;
for($i = 1; $i <= 2; $i++)
{
?>
<tr class="click <?php echo $i; ?>" onClick="visibility('<?php echo $i; ?>');">
<td>Click <?php echo $i; ?></td>
</tr>
<tr id="<?php echo $i; ?>" style="display:none;">
<td>This is a paragraph <?php echo $i; ?></td>
</tr>
<?php
}
?>
</table>
</body>
I am unable to get the desired result(That means only one tr should be visible at a time). There are many existing Jquery plugins available but I do not want to use them as it will increase the load on my web page and so much of customization will be required. I am almost done and hoping to get the desired result with the help from you all.
Thanks in advance
Bind a click handler to your tr.click elements, show the corresponding content, and hide the others:
$(this).next('tr').show().siblings().not('tr.click').hide();
Here's a fiddle
You need to set the display to table-row value when displaying the "tr" element.
Let's make use of jQuery.
$(document).on('click', '.clickablerows', function() {
$('.showablerows').css('display','none');
var showee = $(this).data('showee');
$(showee).css('display','table-row');
return false;
});
I'd add/remove a class and handle the visibility state through that so you have more control over what happens with the active/inactive elements (plus you don't have to care if one of the siblings is the clicked element). Also you can use the event delegation of .on() to save some time attaching the event handler.
jsfiddle
JS
var activeClass = 'active';
$('table').on('click', '.click', function() {
$(this).next().addClass(activeClass).siblings().removeClass(activeClass);
});
CSS
td {
display: none;
}
.active td {
display: table-cell;
}
first set class name "test" for all td's
then use this code
$(".test").click(function(){
$(".test").hide();
$(this).show();
});
I want display and hide HTML div with ajax,
Situation:
progressbar('on');
very_long_function();
progressbar('off');
I want display div when working very_long_function(); , bUt when finish working I want hide div
Progress bar function:
function progressbar($status){
if($status == "on"){
echo "
<script>
$(document).ready(function() { function() {
$('#load').css('display','inline');
});
</script>
";
}
else{
echo "
<script>
$$(document).ready(function() { function() {
$('#load').css('display','none');
});
</script>
";
}
}
Problem is that div not showing when very_long_function(); working, maybe is possible to solve this priblem with AJAX or jQuery
HTML
<div id="load" style="display: none;"><img src="loading_baras.gif" style="width: 550px; height: 10px; margin-top: -10px"></div>
I think, that you architecture is wrong. You have to user JS for it.
Like next:
$(function(){
$('#load').css('display','inline');
$.post('/very_long_function.php', {url: 'http://www.google.com'}, function(result){
alert(result);
$('#load').css('display','none');
});
});
PHP: very_long_function.php
$url = $_POST['url'];
$result = very_long_function($url);
echo $result;
die;
Are sure that you included jquery lib for using it . Also there is no double $$ in jquery.
Please give the html and after we will correct it.
I don't know if I've even asked the question properly, but I have a codeigniter application that some heaving lifting in the back end. While the app is busy executing commands(ajax commands), I'd like to show some sort of a status / message box / div. When the task is done, I'd like to clear the div / box.
What would I need to google to find a solution like this?
Thanks.
Edit:
This is what my jquery / ajax call looks like right now...
$('#availVLANS').click(function() {
$(this).attr("disabled","disabled");
$.ajax({
url:"<?php echo site_url('controller/methodABC/');?>",
type:'POST',
dataType:'json',
success: function(returnDataFromController) {
var htmlstring;
var submitFormHTML;
htmlstring = "<br><br><B>To reassign the port to a new vlan, click on a VlanId below and then click on the OK button</B><br><table class='table table-bordered table-striped'>";
htmlstring = htmlstring + "<th>VlanId</th><th>Name</th>";
for(i = 0; i < returnDataFromController.length; i++) {
//alert(returnDataFromController[i].VlanId);
htmlstring = htmlstring + "<tr><td><a href=>"+returnDataFromController[i].VlanId+"</a></td><td>"+ returnDataFromController[i].Name+"</td></tr>";
}
submitFormHTML = "<form method='post' accept-charset='utf-8' action='" + BASEPATH + "index.php/switches/changeportvlan/"+ $('#ip').val() +"/" + $('#hardwaremodel').val() +"/" + $('#port').val() + "'><input type='text' name='newVlanID' id='newVlanID' style='width:5em;height:1.5em'/> <button type='submit' class='btn' name='saveVlan' id='saveVlan' style='width:10em;height:2em'>Reassign Vlan</button></form>";
//alert(submitFormHTML);
$('#clientajaxcontainer').html(htmlstring);
$('#newvlanform').html(submitFormHTML);
}
});
$(this).removeAttr("disabled");
});
Just use an animated GIF image in an absolutely positioned DIV overlayed on top of the whole page. Just make sure that you overlay an invisible DIV over top of the entire page to prevent clicks on interface elements behind the progress window. Something like this;
╔════════════════════╗
║ #progress-overlay ║
║ ╔════════════════╗ ║
║ ║ #progress-indicator
║ ╚════════════════╝ ║
╚════════════════════╝
The #progress-overlay is a background for the indicator and what you're going for is like a LightBox2 effect but using a progress indicator and small box in the middle of the screen.
You can get animated gif's from here;
http://preloaders.net/
Make sure that your progress/something-is-happening div sits at the top level of the document structure, so somewhere at the top of the body, before any of your other container DIV's. This is done so that the #progress-overlay is rendered at the same level in the DOM as the top level element of your website. When you absolutely position the #progress-overlay, it will appear overtop of everything else on the page.
<html>
<head>
....
</head>
<body>
<div id="progress-overlay">
<div id="progress-indicator">
<img src="images/myprogress.gif" /> Please Wait...
</div>
</div><!--progress-overlay-->
<div id="website-wrapper">
.... web site, layout, content, etc...
</div>
</body>
</html>
The #progress-overlay is hidden by default and then shown overtop when needed. Something like;
#progress-overlay{
position: absolute;
width: 100%;
height: 100%;
background: #000;
opacity: 0.2;
}
#progress-indicator{
position: relative;
margin: 0 auto;
top: 40%;
width: 200px;
height: 50px;
}
Using JQuery you could easily make this appear on demand using;
$(document).ready(function(){
$('#progress-overlay').hide();
});
function showProgressIndicator()
{
$('#progress-overlay').show();
}
You can make use of onreadystatechange event:
http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
If you're doing it through jquery, just show a div with a message and/or a spinner.
jQuery.ajaxSetup({
beforeSend: function() {
$('#loader').show();
},
complete: function(){
$('#loader').hide();
}
});
If you're using jQuery, I propose the following solution:
The jQuery:
$(document).ready(function(){
$("#the_button").click(function(){
var url = "the_controller/the_method"
var data = {the: "data"}
//before the POST takes place, fade-in the message
$("#the_message").fadeIn();
$.post(url, data, function(r){
if(r.success){
//when the post is finished, and it was successful, fade-out the message.
$("#the_message").fadeOut();
}
else console.log("something bad happened");
}, 'json');
});
});
The HTML:
<!-- HIDE IT BY DEFAULT -->
<div id='the_message' style='display:none;'>
Please wait.
</div>
The Controller:
class The_controller extends CI_Controller{
function the_method(){
$p = $this->input->post();
the_task($p);
if(the_task_success) return json_encode(array("success" => true));
else return json_encode(array("success" => false));
}
}