make html table element <td></td> editable - javascript

I pull info from a database table and place it into an HTML table. I want to allow the user to click on a number in the table and be able to edit it. I used jquery to make an event for click but when I use <textarea> it enlarges the cell and messes up the look of the whole table. I've tried <input> and it does the same. Any way that the table cell itself can just be turned into an input? Here's 2 screenshots, first with the table, second to show how the table gets skewed when an input is added.
Screenshot of Table
Screenshot of Table with Textarea
The question is what is my best option for editing text. <textarea> makes the cell larger and honestly it looks ugly... contenteditable doesn't work with IE from the sounds of it, which disqualifies it as an option. My end goal is to save the value back to the database also after its entered which is why I was trying a click with jquery, so it would be easy to add more code to shoot the text back to the DB afterwards
<?php
include("connection.php");
$query= "SELECT * FROM schedule";
$result = mysqli_query($link, $query);
$scheduletext="<table>";
if($result = mysqli_query($link, $query)) {
$b=1;
while ($row=mysqli_fetch_array($result)) {
$scheduletext.="<tr>";
$a=1;
while($a< mysqli_num_fields($result)) {
if(($a == 1)and ($b == 1)){
$scheduletext.="<th></th>";
} else {
if (($a == 1) or ($b == 1)) {
$scheduletext.="<th>".$row[$a]."</th>";
} else {
$scheduletext.="<td>".$row[$a]."</td>";
}
}
$a++;
}
$scheduletext.="</tr>";
$b++;
}
}
$scheduletext=$scheduletext."</table>";
?>
<html>
<head>
<title>TastySnack - Production Schedule</title>
<link href="https://fonts.googleapis.com/css?family=Kaushan+Script" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="tasty.css">
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<div id="top">
<div id="top-left">
TastySnack Production
</div>
<div id="top-right">
<img id="logo" src="images/TastysnackLogo.jpg">
</div>
</div>
<div id="split"></div>
<div id="schedule">
<?php
print_r($scheduletext);
?>
<div id="new"></div>
</div>
<script type="text/javascript">
$("td").click(function(){
$(this).html("<textarea>");
});
</script>
</body>
</html>

Just include contenteditable
into the td where evere you want to have content editable
<td contenteditable>hello world</td>
here is a demo: https://jsfiddle.net/3eav7mLv/

You can use jquery table edit.
http://markcell.github.io/jquery-tabledit/#examples
for edit and delete.
Download and include js table edit file.
Use code from example like this:
$('#example3').Tabledit({
url: 'example.php',
editButton: false,
deleteButton: false,
hideIdentifier: true,
columns: {
identifier: [0, 'id'],
editable: [[2, 'firstname'], [3, 'lastname']]
}});
Where
example.php
can be your route for controller with some logic.

just include <textarea> or <input type="text"> tag within the <td> tag
<td><textarea rows="4" cols="50">Content here</textarea></td>

Related

hiding divs using javascript that don't match the clicked div and pushing correct div up the page

I have a web page in PHP that shows blog posts/ articles that were posted from 2015-2008. basically at the top of the page I have buttons that have the year on it, and below all the blog posts and articles correlatin to the years. I want to have a feature so that if the user clicks 2013, all other posts with years not matching 2013 will dissapear and the correct year posts/articles will move up to the top of the page, so the user doesn't have to scroll.
Here is my code, the content is loaded through a controller so the page is basically created by grabbing data from an array.
<div class="calendar-key">
<div class="cd-timeline2-img cd-2015" id="btn" >'15</div>
<div class="cd-timeline2-img cd-2014" >'14</div>
<div class="cd-timeline2-img cd-2013" >'13</div>
<div class="cd-timeline2-img cd-2012">'12</div>
<div class="cd-timeline2-img cd-2011" >'11</div>
<div class="cd-timeline2-img cd-2010" >'10</div>
<div class="cd-timeline2-img cd-2009" >'09</div>
<div class="cd-timeline2-img cd-2008" >'08</div>
<div class="cd-timeline2-img cd-2007" >'07</div>
<?php foreach ($article as $slug => $article): ?>
<div class="cd-timeline-block">
<div class="cd-timeline-img cd-<?php echo $article['year'] ?>">
<span class="timelinedate"><?php echo $article['month'] ?><?php echo $article['day'] ?></span>
</div>
<div class="cd-timeline-content">
<a href="<?php echo $article['link'] ?>">
<h3 class="press_title" id="<?php echo $article['year'] ?>-<?php echo $article['first'] ?>"><?php echo $article['title'] ?></h3>
<img src="<?php echo $article['image'] ?>" width="100%" height="auto" />
</a>
<p><?php echo $article['description'] ?> </p>
<div class="social-share-buttons article-share-buttons pull-left">
<a class='social-email' href='<?php echo SocialShareLink::email("", "Check out this article, ".$article['title']." \n\n" .$article['link']); ?>'</a>
<a class='social-facebook' href='<?php echo SocialShareLink::facebook($article['link']); ?>' target='_blank'></a>
<a class='social-twitter' href='<?php echo SocialShareLink::twitter("", $article['link']); ?>' target='_blank'></a>
<a class='social-google' href='<?php echo SocialShareLink::googleplus($article['link']); ?>' target='_blank'></a>
</div>
Read more
</div>
</div>
<?php endforeach; ?>
the for each basically takes an array I have in a config file with data, and populates the articles on the page for however many there are in the array.
'articles' => [
'article#1 example' => [
'description' => "exampletextblablabla",
'title' => 'article title',
'link' => '//www.google.com',
'year' => '2015',
'month' => 'Jul ',
'day' => '25',
'first' => '1', //first article of that year
'image' => '../../images/example.jpg'
],
//more articles in this format
and then my failed attempt at js
<script type="javascript">
$('.cd-timeline2-img a').on('click',function(){
var eq = $(this).index();
$('cd-timeline-img cd-<?php echo $article['year'] ?>').removeClass('show');
$('cd-timeline-img cd-<?php echo $article['year'] ?>').eq(eq).addClass('show');
});
</script>
I am not very good at javascript, so I tried something like this but nothing works. I feel like this is an easy little script to right, any help would be great! thanks.
Woohoo! Finally, I got it working and 100% where I want it. So I used your code and threw it into a Fiddle: https://jsfiddle.net/rockmandew/4Lyofmkh/44/
You will see that I went with my approach - by default, the articles are display none and have a class of 'show' on them to begin with - you will also notice I changed where you had your 'cd-(year)' - I did this because you needed to identify the entire article container since that is what you would be hiding/showing.
I also added a 'Show All' button, so the user can view all if desired.
So like I said I changed your HTML markup right here:
<div class="cd-timeline-block cd-2015 show">
<!-- Article Year in Div Class below -->
<div class="cd-timeline-img">
It was "cd-timeline-img cd-2015" previously. That is the only change you need to make to your markup, besides adding the "show all" button (if you want it):
<div class="show-all">Show All</div>
Furthermore, I applied the display:none css property to the ".cd-timeline-block"
.cd-timeline-block {
margin-top:35px;
display:none;
}
Which is why we initialize the page with the "show" class on there:
<div class="cd-timeline-block cd-2015 show">
Which has the following styles:
.show {
display:block;
}
Finally, we get to the meat of it all, the jQuery. I will post the working code that I used and then explain it. The following code is to toggle articles based on the year clicked:
$('.calendar-key a').each(function() {
$(this).on('click', function() {
var x = 'cd-' + $(this).attr('rel');
$('.cd-timeline-block').each(function() {
if($(this).hasClass(x)) {
$('.cd-timeline-block').not(this).each(function() {
if($(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
$(this).each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
}
});
})
});
As you will see, when a ".calendar-key" link is clicked, the clicked link will produce a variable based on the links "rel" - the variable adds the "cd-" prefix onto the "rel" value. Then for each ".cd-timeline-block" if it has the class that was created from clicking (the variable just discussed), it will cycle through all of the ".cd-timeline-block" elements that isn't "this" (meaning all elements that don't match the selected year.) - for all of those elements, if it has the "show" class, it will be toggled. Then the last part, it takes the "this" and cycles through each of them, if it doesn't have the class "show", then it toggles the class "show", thus displaying the desired elements.
Finally, the show all button is controlled with the following function:
$('.show-all a').on('click', function() {
$('.cd-timeline-block').each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
});
Its a fairly simple function. When the ".show-all" link is clicked, it cycles through all of the ".cd-timeline-block" elements, again, if they don't have the "show" class, the function will toggle the "show" class.
I know that was a lot but hopefully it all made sense. Again, here is the associated Fiddle I made to help you.
https://jsfiddle.net/rockmandew/4Lyofmkh/44/
Let me know if you need any further help.
Latest Update:
https://jsfiddle.net/rockmandew/4Lyofmkh/46/
Fiddle now contains new mark-up for easiest solution to updated issue marked in comments below.
It finally dawned on me that I was filtering your list of years not your posts. For future reference post a snippet of actual code, now bits with php all over them. Now the script looks for the rel attribute in your year list for the year, matches that year to the class "cd-year" in each post and filters as necessary. I stripped out all of the superfluous parts of the post like the social links as they're not needed for this exercise.
http://jsfiddle.net/1dyocexe/2/
//this is where you'd have your <?php echo $article['year'] ?> set the current year
var year = 2014;
getPosts(year);
function getPosts(year) {
$(".cd-timeline-block").find("div").each(function (i) {
var elm = $(this);
var cdYear = "cd-" + year;
var use = elm.hasClass(cdYear);
if (use === true) {
elm.show();
} else {
elm.hide();
}
});
}
$(".calendar-key div a").on("click", function () {
var year = $(this).attr("rel");
getPosts(year);
});

Hide div on page but div shows before being hidden

How do I get the <div> not to show at all when the page loads? The div is set to hidden in JS and the <div> hides but its after the <div> has already shown on the page for a brief second.
I am using this popup in my website.
http://mootools.net/forge/p/popupwindow
Here is my code :-
<script type="text/javascript">
App = {};
window.addEvent('domready', function() {
App.popUp1 = new PopUpWindow('', { contentDiv: 'trailerquestion', width: 559 });
App.popUp2 = new PopUpWindow('', { contentDiv: 'popup-redflag', width: 559 });
});
</script>
<?php
function JSLink($text, $onclick) {
return "$text";
}
$asklink=JSLink('<div class="buttonNew greenB bigrounded trailer-button-question"><span>Ask me a question</span></div>', 'App.popUp1.open(); App.popUp1.positionTo(this, 1180, 100);');
?>
<?php
echo $asklink;
?>
<div id="trailerquestion">
<?php
$this->load->view('popup/popupaskmequestion',$results);
?>
</div>
Set the div's display to none with CSS, not Javascript. Then change the display property with Javascript when you want it to be shown.
If you want the div to just be hidden but take up the space it requires, use -
<div id="trailerquestion" style="visibility:hidden">
If you want the div to not take up any space at all and be hidden, use -
<div id="trailerquestion" style="display:none">
Set the element to be hidden with css e.g <div id="trailerquestion" style="display:none">
You might need to set it to display again when you show the dialog if your dialog library doesn't do that for you.

jQuery Tooltip in PHP "while" loop not working

I want to display tool-tips on my website, and I'm using this code: http://flowplayer.org/tools/demos/tooltip/table.html
I'm using a while loop to create table rows <tr>. Here is how my tool-tip <div> looks like:
<td class="maandgem">€ <?= round($monthavg, 2); ?></td>
<div id="tooltip" class="tooltip">
Shipping: <?= $row['price_shipping']; ?><br />
Price: <?= $row['price']; ?><br /><br />
Total: <?php echo $row['price'] + $row['price_shipping'] + ($row['abo_price'] * $row['abo_time']); ?>
</div>
And this works as planned, it calculates the total price for each <tr>. The problem I'm having is that when I hover over the <td class=maandgem> it always shows the same first tool-tip.
So, each <TD> shows only 1 tool-tip, the first one created. Instead of an unique tool-tip for each row. The PHP part works - there are unique <TD>'s being created. I'm using this code (its the default, I don't understand jQuery much)
$(document).ready(function() {
$(".maandgem").tooltip({
tip: '#tooltip',
position: 'bottom left',
delay: 0
});
});
I'm also including this .js, and I have a basic style sheet for the tool-tip.
<script src="http://cdn.jquerytools.org/1.2.6/full/jquery.tools.min.js"></script>
I guess that's because you use an id for the tooltip, and an id have to be unique, therfore jquery only selects the first one.
Try use a class-attribute instead, and select on that.
Yes, If class will be used instead of ID then it will works on loop also.
I have tested it and working fine.
<link rel="stylesheet" href="jquery-ui-1.10.4.custom.css">
<script src="jquery-1.10.2.min.js"></script>
<script src="jquery-ui-1.10.4.custom.js"></script>
<script>
$(function() {
$( ".show-option" ).tooltip({
show:
{
effect: "slideDown",
delay: 250
},
position:
{
my: "center top",
at: "center"
}
});
});
</script>
</head>
<body>
<h2 class="show-option" title="Testing Tooltip">ToolTip</h2>
</body>

Problem with appending HTML and JSTL code in a DIV object using jQuery

What's supposed to happen:
Every time I click an item in a list (single selection), information in that object is displayed on a separate div.
The problem:
I can't get the information to display on the separate div.
Table containing the list and the preview area is supposed to display:
<table id="preview" style="width: 100%;" class="border">
<tr>
<td style="width: 25%;">
<!-- List here -->
</td>
<td style="width: 75%;">
<div id="template_preview" style="overflow:auto">
</div>
</td>
</tr>
</table>
On load, this will be called:
<script type="text/javascript" language="javascript">
$(document).ready(function(){
changePreview();
});
</script>
The changePreview() function:
function changePreview()
{
var selectedValueFromListId = $('#listId').val();
$('#template_preview').html('<c:forEach var="some_var" items="${model.someList}">');
$('#template_preview').append('<input type="hidden" id="someTemplateId" value="${some_var.someListId}" />');
var someTemplateId = $('#someTemplateId').val();
if (selectedValueFromListId == someTemplateId)
{
$('#template_preview').append('test');
$('#template_preview').append('<c:if test="${some_var.objectOne.objectTwo.objectTwoId == valueOfSomething}">');
$('#template_preview').append('some text here - <c:out value="${some_var.label}" />');
$('#template_preview').append('</c:if>');
}
$('#template_preview').append('</c:forEach>');
}
I haven't tested out jQuery's .html() or .append() functions before so I'm not sure if I'm using them right or if what I'm trying to do is possible.
I hope I've explained my problem in enough detail. I've tried researching it in search sites but so far I haven't found a solution.
Thanks in advance.
JavaScript and jQuery gets executed client side, and JSTL gets compiled server side, BEFORE javascript even reach the client and get executed... So you can not expect to print some 'JSTL like' string with jQuery and expect it to work.
The solution for you, is to control the javascript you write to the page with JSTL, and not the contrary:
<script type="text/javascript">
function changePreview() {
var selectedValueFromListId = $('#listId').val();
<c:forEach var="some_var" items="${model.someList}">
$('#template_preview').append('<input type="hidden" id="someTemplateId" value="${some_var.someListId}" />');
var someTemplateId = $('#someTemplateId').val();
if (selectedValueFromListId == someTemplateId) {
$('#template_preview').append('test');
<c:if test="${some_var.objectOne.objectTwo.objectTwoId == valueOfSomething}">
$('#template_preview').append('some text here - ${some_var.label}');
</c:if>
}
</c:forEach>
}
</script>
ps. I'm assuming that everything else is ok, i don't know your model so i can not test it...

Toggle data display inside table cell

I have a table that's generated by a normal PHP loop. What I want to do is create a form in the first column of each row that's hidden by default but appears when you click a toggle link in that row.
I can make a normal toggle-able div by creating a CSS id called hidden and setting display: none;. Unfortunately I can't keep creating divs with id=hidden that are automatically associated with the preceding link.
I am pretty inexperienced with both Javascript and CSS, so I've mostly tried to do this by patching together examples but I'm coming up empty. I've read in some places that you can't put divs inside of a table, so maybe I'm going about this all wrong.
Here's an example of what the code does and how I wish it worked, but of course it does not.
<script language="JavaScript" type="text/javascript">
function toggle(id) {
var state = document.getElementById(id).style.display;
if (state == 'block') {
document.getElementById(id).style.display = 'none';
} else {
document.getElementById(id).style.display = 'block';
}
}
</script>
<?php
while($array = mysql_fetch_array($sql))
{
?>
<tr>
<td>
<?php
echo $array['some_data'];
?>
Toggle
<div id="hidden"><?php echo $array['hidden_thing']; ?></div>
</td>
<td>
<?php echo $array['some_other_data']; ?>
</td>
</tr>
<?php
}
?>
Just use a different ID for each row:
<?php
$count = 0;
while($array = mysql_fetch_array($sql)) {
$id = 'hidden' . $count++;
$data = $array['some_data'];
$hidden = $array['hidden_thing'];
$other_data = $array['other_data'];
echo <<<END
<tr>
<td>$data <a href="#" onclick="toggle('$id');>Toggle</a>
<div id="$id">$hidden_thing</div>
</td>
<td>$other_data</td>
</tr>
END;
}
Make it a span instead of a DIV as I think that some browsers don't support divs inside table elements. Also, instead of referring to it by ID, pass in this.nextSibling() to the toggle, using DOM navigation to get the next sibling (which should be the SPAN) to show/hide.
function toggle(ctl) {
var state = ctl.style.display;
if (state == 'block') {
document.getElementById(id).style.display = 'none';
} else {
document.getElementById(id).style.display = 'block';
}
}
<a href="#" onclick="toggle(this.nextSibling);">Toggle
</a><div><?php echo $array['hidden_thing']; ?></div>
EDIT: As #tomhaigh suggests (and as shown in the example), for this to work you need to make sure that there is no text/whitespace between the anchor and the div. You could also write a function that, given a DOM element, would select the next non-text DOM element and return it. Then pass this to that function and the result to your toggle function.
Here's my recommended (general solution) using jQuery to reference events relatively instead of maintaining ids for each row and form. This also allows you to hide non-active row forms easily, which is a good idea since only one form can be submitted at a time.
HTML:
<table id="tableForms" class="table">
<tr>
<td class="rowForm"><form><span>form1 content</span></form></td>
<td class="showRowForm">click on row to show its form</td>
</tr>
<tr>
<td class="rowForm"><form><span>form2 content</span></form></td>
<td class="showRowForm">click on row to show its form</td>
</tr>
<tr>
<td class="rowForm"><form><span>form3 content</span></form></td>
<td class="showRowForm">click on row to show its form</td>
</tr>
</table>
Javascript:
<script type="text/javascript" src="/assets/js/jquery.min.js"></script>
<script type="text/javascript">
//as soon as the DOM is ready, run this function to manipulate it
$(function() {
// get all tr elements in the table 'tableForms' and bind a
// function to their click event
$('#tableForms').find('tr').bind('click',function(e){
// get all of this row's sibblings and hide their forms.
$(this).siblings().not(this).find('td.rowForm form').hide();
// now show the current row's form
$(this).find('td.rowForm form').show();
}).
// now that the click event is bound, hide all of the forms in this table
find('td.rowForm form').hide();
});
</script>
Demo:
A working demo of this can be found here.

Categories

Resources