I am facing issues with creating a dynamic textarea and 'Add' and 'Edit' buttons for every new paragraph.
DEMO of what I have managed so far:
The 'Add' button is for creating new paragraphs. The user should see a textarea where they enter the content for new paragraph. The first time they click 'Add' button, the text on the button will change to 'Save', the second time they click 'Save' it should append the paragraph to the div and assign it a unique id, which will be used to reference it with the new 'Add' and 'Edit' buttons.
The 'Edit' button is for editing the paragraph from which the 'Edit' button was clicked. To make the paragraph editable I'm using jquery editable (jeditable). Below are appropriate links to jeditable plugin:
plugin documentation
jeditable live demo
All the paragraph load from the back-end. Using PHP to load paragraphs:
<div class="paragraphs">
<?php
foreach($notes['children'] as $overview) :
if ($overview['type'] == 'Paragraph') :
?>
<div id="block1">
<p class='edit1'><?php echo $overview['content']; ?></p>
<p>
<?php if (isset($subject) && $subject==true) : ?>
<div id="para1">
<p><textarea cols="40" rows="2" id="textarea1"></textarea></p>
<button id="add1" class="add1 success tiny">Add</button>
<button id="startEdit1" class="canEdit1 tiny">Edit</button>
</div>
<?php endif; ?>
</p>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
The 'Add' and 'Edit' button functionality:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="<?php echo base_url(); ?>assets/teachers/js/jquery.jeditable.min.js"></script>
<script>
var $subject_id = "<?php echo $subject_id ?>";
var $teacher_id = "<?php echo $teacher_id ?>";
// Define our elements
var $lock = false;
//Make the elements editable
function makeThingsEditable() {
$editables.editable({
emptyMessage : '<em>Please write something...</em>',
callback : function( data ) {
$info.hide();
$info.eq(0).show();
}
});
}
function ajaxRequest(data, method_url, request_type) {
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('HTTP/1.1', '200');
}
});
var eurl = "<?php echo base_url(); ?>edit_flow/" + method_url;
var params = 'inputJson=' + data;
var post = $.ajax({
type: request_type,
url: eurl,
data: params,
success: function(result) {
console.log('result: '+result);
console.log('data: '+params);
},
async: false
});
//alert(post.responseText);
return post.responseText;
console.log(post.responseText);
}
// Edit paragraph button
// Button that toggles the editable feature
var i = 1;
var $editables = $('.edit'+i);
$('.canEdit'+i).click(function() {
if( $editables.is(':editable') ) {
//need to call save action here and pass in updated JSON
if ($(this).text() == 'Save changes')
{
var text = $(".edit"+i).text();
// ajax request
var datum = '{"subject_id":'+$subject_id+',"teacher_id":'+$teacher_id+',"editedContent":"'+text+'"}';
ajaxRequest(datum, 'editNotes', 'POST'); // POST request on editNotes
ajaxRequest(datum, 'loadNotes', 'GET'); // GET request on loadNotes
// jquery request
$.get( "<?php echo base_url(); ?>edit_flow/loadNotes", function( data ) {
var data = '{"subject_id":'+$subject_id+', "teacher_id":'+$teacher_id+', "editedContent":"'+text+'"}';
//console.log(data);
alert( data );
});
}
$editables.editable('destroy');
this.innerHTML = 'Edit';
i++;
} else {
makeThingsEditable();
this.innerHTML = 'Save changes';
// TODO h4kl0rd: make $editables selectable
}
});
// Add paragraph button
i = 1;
$('#textarea'+i).hide();
$('#add'+i).click(function(){
if ( $(this).text() == "Add" ) {
$('#textarea'+i).show();
$(this).text('Save');
$('#textarea'+i).focus(function() {
this.select();
});
}
else if ( $(this).text() == "Save" ) {
if ($('#textarea'+i).val() == ''){
alert('Enter something...');
} else {
$(this).text("Add");
$('#textarea'+i).hide();
var overview = $('#textarea'+i).val();
i++;
$('.paragraphs').append('<div id="block'+i+'"><p class="edit'+i+'">'+overview+'</p><div id="para'+i+'"><p><textarea cols="40" rows="2" id="textarea'+i+'"></textarea></p><button id="add'+i+'" class="add'+i+' success tiny">Add</button><button id="startEdit'+i+'" class="canEdit'+i+' tiny">Edit</button></div></div>');
}
}
});
</script>
Any help is appreciated.
change these:
$('.canEdit'+i).click(function() {
$('#add'+i).click(function(){
to these:
$(document).on('click', '.canEdit'+i, function() {
$(document).on('click', '#add'+i, function() {
What seemed to me is your buttons are dynamic and they can't take direct event binding. So instead you have to delegate the event to the closest static parent which is $('.paragraphs') or to $(document) itself because it is always available.
So if you are using closest static parent then you have to put your event handlers inside doc ready and if you are using $(document) then its not needed.
$(function(){
var i = 1;
var $editables = $('.edit'+i);
$('.paragraphs').on('click', '.canEdit'+i, function() {
// all your edit stuff
});
$('.paragraphs').on('click', '#add'+i, function() {
// all your addstuff
});
});
Related
My problem is that when I press yes on delete confirmation the db record goes away,but if I refresh the page it comes back.
Maybe I have to put the language and the id inside the Ajax URL ?
If yes how can I do this?
Please forgive me I am still learning.
This is my code from delete_table.php
PS: this is how the delete button is on the site for example: delete_table.php?lang=en&id=149
if (isset($_GET['id']) && is_numeric($_GET['id']))
{
$id = $_GET['id'];
if ($stmt = $conn->prepare("DELETE FROM `articles_".LANG."` WHERE id =
? LIMIT 1"))
{
$stmt->bind_param("i",$id);
$stmt->execute();
$stmt->close();
}
else
{
echo "ERROR: could not prepare SQL statement.";
}
This is the delete button from the index.php.
<td><a class='delete' id='del_".$row->id."' href='delete_table.php?lang=".LANG."&id=" . $row->id . "'>Delete</a></td>
This is the delete.js where the jquery and ajax is.
$(document).ready(function() {
// Delete
$('.delete').click(function(event) {
var el = this;
var id = this.id;
var splitid = id.split("_");
// Delete id
var deleteid = splitid[1];
// Confirm box
bootbox.confirm("Are you sure want to delete this article?",
function(result) {
if (result) {
// AJAX Request
$.ajax({
url: 'delete_table.php',
type: 'POST',
data: { id: deleteid },
success: function(response) {
// Removing row from HTML Table
$(el).closest('tr').css('background', 'tomato');
$(el).closest('tr').fadeOut(800, function() {
$(this).remove();
});
}
});
}
console.log('delete_table.php');
});
event.preventDefault();
});
});
this is what you are looking for
function confirmDelete() {
if (confirm("Delete Record?") == true) {
alert("Now deleting");
return true;
} else {
alert("Cancelled by user");
return false;
}
}
<td><a class='delete' id='del_".$row->id."' href='delete_table.php?lang=".LANG."&id=" . $row->id . "' onclick="return confirmDelete()">Delete</a></td>
Confirm method does not accept function as second argument.
The confirm() method returns true if the user clicked "OK", and false otherwise. So Save this result in variable and based on that fire ajax or do nothing.
var result = confirm('Are you sure?');
if(result) {
// fire ajax
}
ADD if(response ==1) then remove row from HTML
// Removing row from HTML Table
$(el).closest('tr').css('background', 'tomato');
$(el).closest('tr').fadeOut(800, function() {
$(this).remove();
});
I have a case where I want to pass a variable inside a function.
The code gives more clarity:
<?php
$id=$_POST['id'];
echo "
<script type=\"text/javascript\">
$(document).ready(function(){
function loadData(page){
$.ajax({
type: \"POST\",
url: \"loadSubscritor.php\",
dataType: \"html\",
data: ({ page:page }),
success: function(msg) {
$(\"#subscritor #container\").ajaxComplete(function(event, request, settings) {
$(\"#subscritor #container\").html(msg);
});
},
error: function(){
alert('alertErr');
}
});
}
loadData(1); // For first time page load default results
$('#subscritor #container .pagination li.active').live('click',function() {
var page = $(this).attr('p');
loadData(page);
});
$('#subscritor #go_bt').live('click',function() {
var page = parseInt($('.goto').val());
var no_of_pages = parseInt($('.total').attr('a'));
if(page != 0 && page <= no_of_pages){
loadData(page);
}else{
alert('Enter a PAGE between 1 and '+no_of_pages);
$('.goto').val(\"\").focus();
return false;
}
});
});
</script>
<h3>Subscritor</h3>
<div id=\"subscritor\">
<div id=\"container\">
<div class=\"pagination\"></div>
</div>
</div>";
?>
As shown in the code,
I would like to know how could I pass $id inside the loadData(page) function .
I get this variable from a post request made with ajax, and need to use it inside the function to pass it has variable to loadSubscritor.php
Any idea on how to do it?
EDIT 1: I guees I wasnt very clear on what I wanted, i want to do this :
function loadData(page){
$.ajax({
data: ({ page:page id:$id }),
Thanks in advance.
Well, if I understood what you are trying to achieve you could replace this :
$id=$_POST['id'];
By this :
$id = isset($_POST['id']) ? $_POST['id'] : 1;
And this :
loadData(1); // For first time page load default results
By this :
loadData($id);
For explanation, if it's first time page load, $id will be set to "1".
Else, this will come from $_POST['id'].
Inside your jquery code you can call a php variable in following way
var current_page = "<?php echo $id; ?>" ;
You can make a local variable and easily use as below:
<?php
$id=$_POST['id'];
echo "
<script type=\"text/javascript\">
var id = \"".$id."\";
$(document).ready(function(){
function loadData(page){
$.ajax
({
type: \"POST\",
url: \"loadSubscritor.php\",
dataType: \"html\",
data: ({ page:page
}),
success: function(msg)
{
$(\"#subscritor #container\").ajaxComplete(function(event, request, settings)
{
$(\"#subscritor #container\").html(msg);
});
},
error:
function()
{ alert('alertErr');
}
});
}
loadData(1); // For first time page load default results
$('#subscritor #container .pagination li.active').live('click',function(){
var page = $(this).attr('p');
loadData(id);
});
$('#subscritor #go_bt').live('click',function(){
var page = parseInt($('.goto').val());
var no_of_pages = parseInt($('.total').attr('a'));
if(page != 0 && page <= no_of_pages){
loadData(id);
}else{
alert('Enter a PAGE between 1 and '+no_of_pages);
$('.goto').val(\"\").focus();
return false;
}
});
});
</script>
<h3>Subscritor</h3>
<div id=\"subscritor\">
<div id=\"container\">
<div class=\"pagination\"></div>
</div>
</div>
";
?>
I got multiple checkboxes and labels and when the answer is correct I want to change the background color of the selected checkbox and label
<input type="checkbox" id="a" class="check-with-label" />
<label for="a" class="question_box">
<?php echo $vraag[0]['A'] ?>
</label>
<input type="checkbox" id="b" class="check-with-label" />
<label for="b" class="question_box">
<?php echo $vraag[0]['B'] ?>
</label>
and when the user presses submit it calls an ajax call to a script to check if it is the correct answer or not.
$('#bottom').on('click', function(){
$('#antwoorden input:checked').each(function() {
var selected = $(this).attr('id');
//var selected_box = this;
selected = selected.toUpperCase();
var data = {
vraag_nummer : <?php echo $vraag[0]['id'] ?>,
antwoord : selected
};
console.log(data);
$.ajax({
type: 'POST',
url : 'includes/check_correct.php',
data: data,
success: function(data) {
if(data.correct){
this.css('background-color', 'green');
//selected_box.css('background-color', 'green');
} else {
this.css('background-color', 'red');
}
},
error: function(err) {
console.log('error');
console.log(err);
}
});
});
});
problem is I don't know how to call the correct box because when the user presses submit the this variable is now the submit button and not the checked box (There can only be one checkbox selected at the time_.
So the question is how do I replace the background color of the selected AND the correct box from
.check-with-label:checked + .question_box {
background-color: orange;
}
to
background-color:green
(and for incorrect red)
Try changing the label instead of this
You've already got the ID of the label
(var selected = $(this).attr('id');)
Which will probably return a/b/c/d and then use
$('label[for="'+selected+'"]').css('background-color', 'green'); //or red in the else statement
this styles the label for the selected id, in this case d
the code above basicly means:
$('label][for="d"].css('background-color','green'); //or red
but then using the chosen variable
Goodluck!
In success use selected_obj.css instead of this.selected and pass $(this) to selected_obj
$('#bottom').on('click', function(){
$('#antwoorden input:checked').each(function() {
var selected = $(this).attr('id');
var selected_obj = $(this);
//var selected_box = this;
selected = selected.toUpperCase();
var data = {
vraag_nummer : <?php echo $vraag[0]['id'] ?>,
antwoord : selected
};
console.log(data);
$.ajax({
type: 'POST',
url : 'includes/check_correct.php',
data: data,
success: function(data) {
if(data.correct){
selected_obj.css('background-color', 'green');
//selected_box.css('background-color', 'green');
} else {
selected_obj.css('background-color', 'red');
}
},
error: function(err) {
console.log('error');
console.log(err);
}
});
});
});
Try this
$('#bottom').on('click', function(){
$('#antwoorden .check-with-label').each(function() {
var selected = $(this).attr('id');
var isChecked = $(this).is(':checked'));
if (!isChecked) {
return;
}
var selected_obj = $(this);
//var selected_box = this;
selected = selected.toUpperCase();
var data = {
vraag_nummer : <?php echo $vraag[0]['id'] ?>,
antwoord : selected
};
console.log(data);
$.ajax({
type: 'POST',
url : 'includes/check_correct.php',
data: data,
success: function(data) {
if(data.correct){
selected_obj.css('background-color', 'green');
} else {
selected_obj.css('background-color', 'red');
}
},
error: function(err) {
console.log('error');
console.log(err);
}
});
});
});
After the page is rendered and displayed to user, PHP will no longer run. Therefore, in your $('#bottom').on('click' function, the PHP code won't work. The trick is to store that information when building the page, such as by writing it into a data attribute or some such.
Inside the AJAX success function the $(this) object is not available. Set it to a global variable and you will be able to access the value.
/* javascript/jQuery */
$('#bottom').on('click', function(){
$('#antwoorden input:checked').each(function() {
var selected = this.id; //faster, same result
$this = $(this);
selected = selected.toUpperCase();
var data = {
//change next line - PHP finished running
vraag_nummer : $this.attr('data-vn'),
antwoord : selected
};
console.log(data);
$.ajax({
type: 'POST',
url : 'includes/check_correct.php',
data: data,
success: function(data) {
if(data.correct){
$this.css('background-color', 'green');
} else {
$this.css('background-color', 'red');
}
},
error: function(err) {
console.log('error');
console.log(err);
}
});
});
});
<!-- HTML: -->
<input id="vraag_nummer" data-vn="<?php echo $vraag[0]['id'] ?>" type="text" />
ok let me try to explain this as detail as I can.
I have these different inputs. It has passenger names, ticket numbers and rloc.
I am trying to search the passengers let's say by ticket number.
I have this search button to search into the database for the ticket number.
I got the ticket number and I am trying to find the next ticket number by clicking the next button. It works up to this point. (these are done by using ajax)
What is making me stuck is. If I didn't refresh the page, the database would stay to the database used when I click next.
sample if I input 111 searched the record, pull it out and I click next it'll go for record 112 then 113 with another click but without refreshing the page, I input 111 and search which still works but if I click next again it'll show the record of 114 instead of 112.
I thought it might be something about the .on() event for binding purpose but still not getting it right. Can someone give me an extra eyes please? Thank you.
Here is my html which is really basic
<div class="container">
<div class="title">
<h1>Ticket search</h1>
</div>
<div class="update-info">
<h3>{{$num}} files have been convert and updated.</h3>
</div>
<div class="sub-container">
<div class="form-field">
<label>Ticket Number : </label>
<input class="ticket-field" type="text" name="ticketNumber" value="" placeholder="Please enter ticket number">
</div>
<div class="button-field">
<input type="submit" class="btn-search"value="Search">
<button class="btn-update">Update</button>
<button class="btn-prev" name="previous">PREV</button>
<button class="btn-next" name="next">NEXT</button>
</div>
<input type="hidden" name="ticketHolder" value="">
</div>
<div id="text-field">
</div>
</div>
my js search using jquery and ajax
$("div.container").on("click", ".btn-search", function(event) {
event.preventDefault();
var noError = true;
var ticketNumber = $.trim($("input[name='ticketNumber']").val());
if($.isNumeric(ticketNumber) || ticketNumber==""){
noError = true;
}else{
noError = false;
$("input[name='ticketNumber']").val('');
alert("please enter a number");
}
if(noError){
$("#text-field").empty();
$.ajax({
method: "post",
url: "/search",
dataType: "json",
data: {ticketNumber:ticketNumber},
success: function(data){
if(data.length>1){
$.each(data,function(index,item){
$("#text-field").append("<h3 class='block-hearder'><span>"+item['dateOfFile']+"</span><span>"+item['paxName']+"</span><span>"+item['airlineName']+"</span></h3><div class='text-block'>"+item['content']+"</div>");
});
$( "#text-field" ).accordion( "destroy" );
$( "#text-field" ).accordion({
collapsible: true
});
}else{
$.each(data,function(index,item){
$("#text-field").append("<div class='text-block-single'>"+item['content']+"</div>"+"<script>");
searchNext(item['systemName'],item['ticketNumber']);
if(item['content'].indexOf('S') != 0){
$('.btn-prev').button( "enable" );
$('.btn-next').button( "enable" );
}
});
}
$("input[name='ticketNumber']").val('');
}
});
}
}); //end btn-search
my searchNext() for js
function searchNext(systemName, ticketNumber){
var systemName = systemName;
var ticketNumber = Number(ticketNumber);
// Making sure this function doesn't get called twice
if( !this.wasRun ){
$(".btn-next").click(function(event) {
event.preventDefault();
$.ajax({
method: "post",
url: "/next",
dataType: "json",
data: {systemName: systemName, ticketNumber: ticketNumber},
success: function(data){
$("#text-field").empty();
$("#text-field").append("<div class='text-block-single'>"+data['content']+"</div>");
if(data['content'].indexOf('>') > 0){
if((ticketNumber + 1) == data['ticketNumber']){
ticketNumber++;
searchNext(ticketNumber, data['systemName']);
}
}else{
$('.btn-next').button( "disable" );
}
}
});
}); //end btn-next
}
this.wasRun = true;
} //end searchNext()
in my php, my search()
public function search(){
$data = array();
/* Check if ticket number entered is not null and is number */
if(($_POST['ticketNumber'] != null) && (is_numeric($_POST['ticketNumber']))){
$ticketNumber = trim($_POST['ticketNumber']);
}else{
$ticketNumber = "";
}
if(strlen($ticketNumber) == 10 ){
$model = Document::where('ticketNumber', '=', $ticketNumber)->get();
}else{
$data['content'] = 'entery valid ticket number (10 numbers)';
}
$index = 0;
if(sizeof($model)>0){
foreach ($model as $key => $value) {
$document = $value->getAttributes();
$data[$index]['content']=$document['fileContent'];
$data[$index]['dateOfFile']=$document['dateOfFile'];
$data[$index]['systemName']=$document['systemName'];
$data[$index]['ticketNumber']=$document['ticketNumber'];
$index++;
}
}else{
$data[$index]['content'] = "Sorry the document does not exist, or hasn't been update yet, please click update and try again.";
}
echo json_encode($data);
} //End search function
in my php next() which searches the next record
public function next(){
$data = array();
$systemName = $_POST['systemName'];
$nextTicketNumber = $_POST['ticketNumber'] + 1;
//used to get the nextTicketNumber if there is a sequential nextTicketNumber
$model = Document::where('systemName', '=', $systemName)
->where('ticketNumber', '=', ($nextTicketNumber))->get();
if(sizeof($model) == 0){
$data['content'] = 'Reached end of record';
return json_encode($data);
}
//Getting all the same system number and stores the tickets in an array to find the max ticketNumber
$getAllModel = Document::where('systemName', '=', $systemName)->get();
$allTicketNumber = [];
if(sizeof($getAllModel) > 0){
foreach($getAllModel as $key => $value){
$allTicketNumber[] = $value->ticketNumber;
}
}
$maxTicketNumber = max($allTicketNumber);
if($nextTicketNumber > $maxTicketNumber){
$data['content'] = 'Reached end of record';
}else{
$data['content'] = $model[0]->fileContent;
$data['ticketNumber'] = $model[0]->ticketNumber;
$data['systemName'] = $model[0]->systemName;
}
echo json_encode($data);
}
I have a collapsible part of my jQuery Mobile page that are generated from PHP output from a MS Sql databas and content render as I like it to so that part is ok.
in each section I create a form with 3 buttons and they are supposed to have unique Id:s.
All forms are also created to have a unique id created in runtime.
actions.php (renders out my elements into mobilepage i a DIV)
$counter=0; reset counter for ID:s
while (odbc_fetch_row($rs)){
// data output from Db to make like 10 collapsible with different data
$html = "";
$html = "<div data-role='collapsible-set' data-mini='true'>";
$html.="<div data-role='collapsible' data-mini='true'>";
$html.="<h3><span style=float:left;><img src='../_pic/$image' alt='$imageText' /> ".substr($Time,0,16)." $Area</span><span style='float:right;' class='ui-btn-up-c ui-btn-corner-all' cnt> $data </span></h3>";
$html.="<p>ID: $ID $Id $Status<br />$Status $Description)</p>";
$html.="<form method='post' action=''>";
$html.="<button value='action1' id='action1$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<button value='action2' id='action2$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<button value='action3' id='action3$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<input type='hidden' id='id$counter' name='id' value='$dataName' />";
$html.="</form>";
$html.="</div>";
$html.="</div>";
echo utf8_encode($html);
$counter++; //upcount to make Id:s unique
} //end While
Then I have this function that listens for a button that submit:
$(':submit').live('click', function() {
var button = $(this).val();
if (button == 'action1') {
$.ajax({
url: '../_php/Functions.php',
data: 'button=' + $(this).val()+'&id='+$('#id').val(),
async: true,
beforeSend: function() {
$.mobile.showPageLoadingMsg(true);
},
complete: function() {
$.mobile.hidePageLoadingMsg();
},
error: function (request,error) {
alert('error');
}
});
}
return false;
});
I cant seem to get another id than the first one since i need to make all ID:s unique in my forms and all I do now is to check: &id='+$('#id').val(). what I would like to have done is to link the button pressed-id number to my hidden field id-number so i get the right data out from it. As of now I only get the first form:s id evaluated...
If someone could point me in the right direction how to make that happen i´d be greatful.
functions.php (a switch statement is pre-testing for submit:ed action
function actions1(){
try {
if(isset($_GET['id'])){
do stuff with 'id'
}else{
do other stuff with 'id'
}
} catch(Exception $e) {
show error
}
}
If some part is unclear or if you feel I missed posting somepart - let me know. /thanks
Within event handlers this referes to the element
$(':submit').live('click', function(){
var id= this.id;
var button = $(this).val();
/* traverse within form to set hidden input, no need to worry about using ID's for them*/
$(this).closest('form').find('input[name=id]').val(id);
/* then in ajax */
data: 'button=' +button+'&id='+id,
})
Not full code....I left some of your code out for simplicity
You can use jQuery .attr() function to get an id or any other attribute value of an element.
$(':submit').live('click', function() {
var button = $(this).val();
var id = $(this).attr("id");
if (button == 'action1') {
$.ajax({
url: '../_php/Functions.php',
data: 'button=' + $(this).val()+'&id='+ id,
async: true,
beforeSend: function() {
$.mobile.showPageLoadingMsg(true);
},
complete: function() {
$.mobile.hidePageLoadingMsg();
},
error: function (request,error) {
alert('error');
}
});
}
return false;
});
The solution was to go by attributes name of my hidden input.
var id = $(this).closest("form").find(':hidden').val();