JavaScript won't show/hide div - working with PHP/MySQL - php

In my PHP/MySQL while loop when selecting data for an activity feed, I'm trying to show comments underneath each post so that when you click "show", it shows all of the comments.
I'm using the following code in the while loop (so this is dynamically displayed numerous times for each separate update):
<script language="javascript">
function toggle' . $act_item_id . '() {
var ele = document.getElementById("toggleText' . $act_item_id . '");
var text = document.getElementById("displayText' . $act_item_id . '");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "show";
}
else {
ele.style.display = "block";
text.innerHTML = "hide";
}
}
</script>
<a id="displayText' . $act_item_id . '" href="javascript:toggle' . $act_item_id . '();">show</a>
<div id="toggleText' . $act_item_id . '" style="display: none">' . $responseList . '</div>
' . $act_item_id . ' contains the ID of the update, making everything unique.
When you click show, the JavaScript doesn't show the div.
FYI: Content is loaded into another page via an AJAX call.
AJAX call is as follows:
function list_activity(){
var hr = new XMLHttpRequest();
hr.onreadystatechange = function(){
if (hr.readyState==4 && hr.status==200){
document.getElementById("viewActivity").innerHTML = hr.responseText;
}
}
hr.open("GET", "listActivity.php?t=" + Math.random(), true);
hr.send();
}

I'm not entirely sure you can create and call JS functions like that. Besides, I don't see any reason to re-create the function for each section. Why don't you simply parameterize you function and change the parameter each time through?
Define function once
<script>
function toggle(act_item_id) {
var ele = document.getElementById("toggleText' . act_item_id . '");
var text = document.getElementById("displayText' . act_item_id . '");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "show";
}
else {
ele.style.display = "block";
text.innerHTML = "hide";
}
}
</script>
Then you can loop through
while (some condition) {
...
<a id="displayText' . $act_item_id . '" href="javascript:toggle('.$act_item_id.');">show</a>
<div id="toggleText' . $act_item_id . '" style="display: none">' . $responseList . '</div>
...
}

Related

add [and] + [or ] to search filter for a foreach generated list

So I already have a search filter in place but now I want it to have the ability to combine search phrases. Below is the code that generates a list on page.
<div class="sortable2">
<ul class="connectedSortable links loadfiles" id="loadfiles">
<?php
foreach ($result as $value) {
list($classname, $origin, $name) = explode('_', $value);
$classname = trim($classname, '[]');
$origin = trim($origin, '[]');
$name = pathinfo($name, PATHINFO_FILENAME);
echo "<li class='audiofile " . $name . " " . $classname . "' id='" . $value . "'>".
"<a class='btn_clone fa fa-clone' aria-hidden='true' id='' onclick='repeat(event)' title='Clone'> </a>".
"<a class='btn_addto fa fa-arrow-up' aria-hidden='true' id='' onclick='addto(event)' title='Add to playlist'> </a>".
"<a class='btn_removefrom fa fa-trash' aria-hidden='true' id='' onclick='removefrom(event)' title='Remove element'> </a>".
"<span class='audioclass'>" . $classname . "</span>".
"<a href='" . $directoryname . "/" . $value . "' target='_blank'>".
"<img src='images/avatars/" . $classname . ".jpg'>".
"<div class='audiotext'>".
"<span class='audiotitle'>" . $name . "</span>".
"<span class='audioorigin'>" . $origin . "</span>".
"</div>".
"</a>".
"</li>";
}
?>
</ul>
</div>
This list basically generates blocks like:
frank
hello how are you
link to audio file
william
i am fine
link to audio file
frank
what?
link to audio file
The filtering is done by this code
$('#global_filter').keyup(function() {
var col_name = $(this).attr('class');
var search_val = $(this).val().toLowerCase();
$('.' + col_name).closest('#loadfiles > li').css('display', 'none');
$('.' + col_name).each(function() {
var val = $(this).text();
console.log($(this).text(), 'text');
if(val.toLowerCase().indexOf(search_val) >= 0) {
$(this).closest('#loadfiles > li').css('display', 'block');
}
});
});
which works together with
<div class="input">
<h4>Search field</h4>
<div class="all_all" id="filter_global">
<div align="left"><input type="text" name="global_filter" id="global_filter" class="audiofile"></div>
<div align="left"><input type="checkbox" name="global_regex" id="global_regex" ></div>
<div align="left"><input type="checkbox" name="global_smart" id="global_smart" checked></div>
</div>
</div>
Question
How can I change the filter to allow for multiple searchphrases with [AND] and maybe also [OR] if possible. So the user can type in for instance:
frank [and] hello
and this will then return
frank
hello how are you
link to audio file
Although this project appears to have not been updated in quite some time, you can probably utilize parts of it to work for your needs: https://github.com/bloomtime/boolean-expression-js
$('#global_filter').keyup(function() {
// Init
var col_name = $(this).attr('class');
var search_val = $(this).val().toLowerCase();
// Setup boolean expression
var parsed = new Expression(search_val);
$('.' + col_name).closest('#loadfiles > li').css('display', 'none');
$('.' + col_name).each(function() {
var val = $(this).text();
if(parsed.test(val) == true) {
$(this).closest('#loadfiles > li').css('display', 'block');
}
});
});
It utilizes ReParse behind the scenes to be able to split your search on pre-defined grammar and then test for matching.
Edit
If you are really trying to keep it super simple, it may not be extremely flexible, but you could try this approach. This basically gives the ability to search using [AND] or using [OR] but not both. Could probably use some refactoring as I just quickly whipped it up.
$('#global_filter').keyup(function() {
// Init
var col_name = $(this).attr('class');
var search_val = $(this).val().toLowerCase();
var columns = $('.' + col_name);
// If doing a boolean AND
if (search_val.toLowerCase().indexOf('[and]') >= 0) {
// Get search parts
var parts = search_val.split('[and]');
$(columns).each(function(columnIndex, column) {
var val = $(column).text();
var matched = true;
$(parts).each(function(partIndex, part) {
// Since AND is inclusive, failing to match should assume this column is a non-match
if (val.toLowerCase().indexOf(part.toLowerCase()) < 0) {
matched = false;
// Break early
return false;
}
});
if (matched) {
$(column).closest('#loadfiles > li').css('display', 'block');
}
});
}
// If doing a boolean OR
else if (search_val.toLowerCase().indexOf('[or]') >= 0) {
// Get search parts
var parts = search_val.split('[or]');
$(columns).each(function(columnIndex, column) {
var val = $(column).text();
var matched = false;
$(parts).each(function(partIndex, part) {
// With OR, if ANY of the parts match then it is a match
if (val.toLowerCase().indexOf(part.toLowerCase()) >= 0) {
matched = true;
// Break early
return false;
}
});
if (matched) {
$(column).closest('#loadfiles > li').css('display', 'block');
}
});
} else {
var val = $(this).text();
if(val.toLowerCase().indexOf(search_val) >= 0) {
$(column).closest('#loadfiles > li').css('display', 'block');
}
}
});

How can I store JavaScript from within a jQuery [each] loop to a php variable

I am [successfully] storing a snippet of jQuery inside a php variable, with values inside the snippet being populated by php script like so:
...//collect necessary variables
$script = "
<script type='text/javascript'>
(function($) {
analytics.identity('" . $cid . "', {
created: '" . $created . "',
email: '" . $email . "',
...: '" . $whatever . "'
});
})(jQuery);
</script>
";
return $script;
I can also [successfully] get the name attribute of all forms on the page like so:
<script type='text/javascript'>
(function($) {
$('form').each(function() {
var formname = $( this ).attr('name');
if(formname !== undefined) {
console.log(index + ':' + encodeURIComponent(formname));
};
});
})(Jquery);
</script>
The problem I'm having (maybe obviously) is the lack of experience with javascript to know how to incorporate the two so my $script would look like so:
$script = "
<script type='text/javascript'>
(function($) {
analytics.identity('" . $cid . "', {
created: '" . $created . "',
email: '" . $email . "',
...: '" . $whatever . "'
});
analytics.trackForm($('form[name="formname1"]'),'Form Submitted', {
lead: formname
});
analytics.trackForm($('form[name="formname2"]'),'Form Submitted', {
lead: formname
});
...//(n) number of form names
})(jQuery);
</script>
";
Latest script added directly to the footer:
<script type="text/javascript">
(function($) {
$('form').each(function() {
var formname = $(this).attr('name');
if( formname !== undefined) {
console.log( formname );
var forms = $('form[name="' + formname + '"]');
var trackforms = analytics.trackForm(forms, 'Submitted Optin Form', { leadmagnet: "'" + formname + '"' });
return trackforms;
}
});
})(jQuery);
</script>
Console.log outputs the one form currently on the page, and if I add another, it outputs that correctly also, but the rest of the code is simply written as is and I'm not getting it.
Thanks again.
document.write(...) is adding the string to the document not to the script.
You need to return the functions you want.
$script = "
<script type='text/javascript'>
(function($) {
analytics.identify('" . $ifs_id . "', {
created: '" . $created . "',
email: '" . $email . "',
firstName: '" . $first_name . "',
leadsource: '" . $lead_source ."'
});
$('form').each(function( index ) {
var formname = $( this ).attr('name');
if( formname !== undefined) {
//console.log( index + ':' + formname );
var forms = $('form[name=\"+formname+\"]);
var trackform = analytics.trackForm(forms, 'Submitted Opt In Form', {
leadmagnet : $( this ).attr('name')
});
return trackform;
}
});
})(jQuery);
</script>
";
return $script;

Different Jquery hover popup divs on different links

I've a php for loop which finds data from an Json object, and creates based on these information different divs and different links:
echo $remoteTownFB . " - " .
"<a href=\"#\" id=" . $remoteTownFB . "_trigger>" .$eventName . "</a></br>";
After that, I wrote a Java Script to create different divs (with different names) wich should pop up on mouseover (with a Jquery Script)
<script type="text/javascript">
var samplediv = document.createElement('div');
samplediv.id = '<?php echo $remoteTownFB . "_info" ?>';
var txt = document.createTextNode("Informationen über: <?php echo $eventName?>");
document.getElementById('pop-up').appendChild(samplediv);
document.getElementById('pop-up').appendChild(txt);
</script>
My problem is now the Jquery Script. I tried around with $.each on an Array where every Town name is in, but I couldn't figure it out.
This is my base:
$(function() {
var moveLeft = 20;
var moveDown = 10;
$('a#trigger').hover(function(e) {
$('div#pop-up').show().;
}, function() {
$('div#pop-up').hide();
}
);
$('a#trigger').mousemove(function(e) {
$("div#pop-up").css('top', e.pageY + moveDown).css('left', e.pageX + moveLeft);
});
});
Any help or ideas?
First of you forgot to close the id-property:
echo $remoteTownFB . " - " .
"" .$eventName . "</br>";
Then, for the pop-up to work you could try:
<script type="text/javascript">
var samplediv = document.createElement('div');
samplediv.id = '<?php echo $remoteTownFB . "_info" ?>';
samplediv.style.display = 'none';
var txt = document.createTextNode("Informationen über: <?php echo $eventName?>");
samplediv.appendChild(txt);
document.getElementById('pop-up').appendChild(samplediv);
</script>
The jquery part would be:
<script type="text/javascript">
$(function() {
$('a[id$="_trigger"]').hover(
function() {
var targetSelector = '#' + this.getAttribute('id').replace('_trigger', '_info');
$('#pop-up, ' + targetSelector).show();
},
function() {
var targetSelector = '#' + this.getAttribute('id').replace('_trigger', '_info');
$('#pop-up, ' + targetSelector).hide();
}
);
});
</script>
I'm not really sure what you are trying to do with the mousemove call so I left that alone.

object HTMLLIElement getting outputted instead of expected value

Hey I have a problem in Javascript-PHP variable passing
heres my php code:
<li id="' . $todo1 . '" class="items">' . $todo1 . '<button onclick="ajaxdelete(' . $todo1 . ')">Delete</button></li>
and heres the javascript function
function ajaxdelete(x){
var hr = new XMLHttpRequest();
var url = "ajaxtododelete.php";
var vars = "todo="+x;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("status").innerHTML = return_data;
}
}
hr.send(vars); // Actually execute the request
}
and hers my ajax file:
<?php
session_start();
include_once "connect_to_mysql.php";
$todo = $_POST['todo'];
print "$todo";
$sql = mysql_query("DELETE FROM todo WHERE todo='$todo'");
?>
So instead of outputting the value of '$todo1'(which is wat i want) it outputs :
object HTMLLIElement.Any way around this?
First, you have a major hole in your application for SQL injection. Second, you need to quote the identifer so you are passing the value of the id in the function call instead of a reference to the element itself. Third, you probably ought to be using a framework for this and applying the handlers unobtrusively.
'<li id="' . $todo1 . '" class="items">' . $todo1 . '<button onclick="ajaxdelete(\'' . $todo1 . '\')">Delete</button></li>'
better (using jQuery)
'<li id="' . $todo1 . '" class="items">' . $todo1 . '<button>Delete</button></li>'
<script type="text/javascript">
$(function() {
$('.items').on('click', function() {
var $li = $(this).closest('li');
id = $li.attr('id');
$.post( "ajaxtodelete.php", { "todo" : id }, function() {
$li.remove();
});
});
});
</script>
And fix your PHP to use a parameterized query instead of string concatenation in case someone decides to modify the ids using a browser debugger and change the id in to a SQL command that will drop your entire database -- or retrieve its contents for more nefarious purposes.

Function Calls for Dynamically Loaded Content

I have a PHP file that serves up some HTML populated from a MySQL database and is loaded into the DOM. This data is loaded via jQuery load() method into the #navContent divide of the HTML document. This functions as planed.
At the very-bottom of the HTML doc, I have a click function that targets the #navItem div (see the first echo line of the php file) that was dynamically loaded into the DOM but this does not fire. I know the #navItem tag ID is there because my CSS styles it correctly.
What do I have wrong? For now, I just want all the divides that were dynamically created into the #navContent div to click thru to a URL.
I am a newB and just learning jQuery so corrected code would be very helpful. Thnx
In the HTML:
<html>
<head>
<script type="text/javascript">
. . .
var ajaxLoader = '';
var dns = 'http://www.someURL';
var navContent = '/folder/my_list.php';
var bodyContent = '/folder/index.php/somestuff #content';
$(document).ready(
function() {
loadPage(dns + navContent, "navContent");
loadPage(dns + bodyContent, "bodyContent")
});
. . .
</script>
. . .
</head>
<body>
. . .
<div id="navPanel">
<div id="navHeader">
<img src="images/ic_return.png" style="float: left;"/>
<img id="listSortBtn" src="images/ic_list_sort.png" style="float: right;"/>
<h4 id="navHeaderTitle"></h4>
</div>
<div id="navScrollContainer" class="navContentPosition">
<div id="navContent">NAVIGATION CONTENT GETS DUMPED IN HERE</div>
</div>
</div>
. . .
</body>
<!-- ================ Functions ===================================== -->
<!-- **************************************************************** -->
<script type="text/javascript">
/* --------------- Handle Pg Loading ----------------- */
function loadPage(url, pageName) {
$("#" + pageName).load(url, function(response){
$('#navHeaderTitle').text($(response).attr('title'));
// transition("#" + pageName, "fade", false);
});
};
/* ------------- Click Handler for the Nav Items------ */
$("#navItem").click(function(e) {
e.preventDefault();
var url = 'http://www.google.com';
var pageName = 'navContent';
loadPage(url, pageName);
});
. . .
</script>
</html>
Served PHP File:
<?php
$con = mysql_connect("localhost","root","pw");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("andaero", $con);
$result = mysql_query("SELECT * FROM some_list");
while($row = mysql_fetch_array($result))
{
echo "<div id='navItem' title='My Nav Title'>";
echo "<h1>" . $row['label'] . "</h1>";
echo "<h2>" . $row['title'] . "</h2>";
echo "<p>" . $row['description'] . "</p>";
echo "</div>";
}
mysql_close($con);
?>
You need to initialize that click method AFTER the DOM has been appended with your custom markup. This is a perfect example of a case where OOP programming would do wonders.
You also didn't load the click method into the doc-ready...
<script type="text/javascript">
function MyConstructor()
{
this.ajaxLoader = '';
this.dns = 'http://www.someURL';
this.navContent = '/folder/my_list.php';
this.bodyContent = '/folder/index.php/somestuff #content';
this.loadPage = function( url, pageName )
{
$("#" + pageName).load(url, function(response){
$('#navHeaderTitle').text($(response).attr('title'));
});
this.toggles();
}
this.toggles = function()
{
var t = this;
$("#navItem").click(function(e) {
e.preventDefault();
var url = 'http://www.google.com';
var pageName = 'navContent';
t.loadPage(url, pageName);
});
}
/**************************************
*Init Doc-Ready/Doc-Load methods
**************************************/
this.initialize = function()
{
this.loadPage( this.dns + this.navContent, "navContent");
this.loadPage( this.dns + this.bodyContent, "bodyContent");
}
this.initialize();
}
$( document ).ready( function(){
var mc = new MyConstructor();
//now, you can go ahead and re-run any methods from the mc object :)
//mc.loadPage( arg, 'ye matey' );
});
</script>

Categories