jQuery POST refreshing the page - html

I have some jQuery that takes the value of a text input and puts it into a MySQL database. However, when the jQuery runs, the page refreshes and the variables in the form appear in the URL almost as GET variables. However, none of the variables are GET. Ideally, I would like the page not to refresh.
jQuery:
$('.commentBox').keypress(function(e) {
if(e.which == 13) {
if ($.trim($(this).val()) == ""){
$('#nocomment').modal('show');
}
else {
var form = $(this).siblings('.commentForm');
var commentbox = $(this).val();
$.ajax({
type: "POST",
url: "../comment",
data: form.serialize(),
success: function(){
commentbox.val('');
form.siblings('.commentContainer').append(response);
}
});
}
}
});
HTML (echoed from PHP):
<form class='commentForm'>
<input type='hidden' name='record_id' value='$answerid[$f]' />
<input type='hidden' name='question_id' value='$q' />";
<input type='text' class='commentBox' placeholder='...comment' name='comment' autocomplete='off' />";
</form>

You have to either return false or prevent default, which will stop the form from submitting:
$('.commentBox').keypress(function(e)
{
if(e.which == 13)
{
e.preventDefault(); // <-- This will stop the form from submitting.
if ($.trim($(this).val()) == "")
{
$('#nocomment').modal('show');
}
else
{
var form = $(this).closest('.commentForm');
var commentbox = $(this).val();
$.ajax({
type: "POST",
url: "../comment",
data: form.serialize(),
success: function(){
commentbox.val('');
form.siblings('.commentContainer').append(response);
}
});
}
}
});

You need to prevent the default action from taking place when hitting the enter key, which is form submission via GET.
e.preventDefault();
$( '.commentBox' ).keypress(function( e ) {
if( e.which === 13 ) {
// Prevent the default only when it's the enter key
e.preventDefault();
if ( $.trim($(this).val()) === '' ){
$('#nocomment').modal( 'show' );
}
else {
var form = $( this ).siblings( '.commentForm' );
var commentbox = $( this ).val();
$.ajax({
type: "POST",
url: "../comment",
data: form.serialize(),
success: function(){
commentbox.val( '' ;
form.siblings( '.commentContainer' ).append( response );
}
});
}
}
});

Related

How can I create a user tagging system in a contentEditable div?

I am trying to build a user input (content Editable div) for a chat where someone can write something and tag someone like hello #user32. My problem is when I type # list is open and tag but when I write some text and press enter then type # list is not shown. Position is same and carry last word with #.
<script>
function contentTag(e,t){
let sentence = t.value;
//alert(sentence);
var endpos = t.selectionEnd;
var result = /\S+$/.exec(sentence.slice(0, endpos));
var lastWord = result ? result[0] : null;
//console.log(endpos);
if ((lastWord && lastWord.indexOf("#") == 0) ? lastWord :"") {
let name = lastWord.replace('#', '');
// $("#result").hide();
$.ajax({
type: 'POST',
url: '<?php echo $link->link('ajax', backend); ?>',
data: "Name=" + name,
success: function(data) {
// alert(data);
var test = data;
if (test != undefined) {
$("#result").show();
$("#result").html(data);
}
if (test == ' ') {
$("#result").hide();
}
}
})
} else {
$("#result").hide();
}
});
</script>
<html>
<head>
</head>
<body><div contenteditable="true" id="contentive" onkeyup="contentTag(event,this)" ></div>
</body>
</html>

How to count from 1 when remove a row ajax?

I have to make a functionality that users can add and remove rows with input fields. Problem is that I need a row index (number) in front of each row incorrect order(1., 2., 3. etc.) also when one or more rows are removed and then added again. I can add rows but I can`t get the counting right because If I remove them then the count starts with 4 but I need 1 or if the second row gets removed then I need 2 instead of 4.
I have made it with append() and so far so good but I also need row cont in front of each row. I have a counter but let's say I add 1 row and it gives numbers 1 and 2. If I remove the second row and add another again, now the count is 1 and 3
Note that the "add" button is only one and separated from append();
I have three lines that are 1, 2, and 3, respectively
Now I will delete one of them. For example, I delete row number 2. I see this demo,
This should not happen. It should show the numbers 1 and 2, respectively.
<script>
$(document).ready(function() {
$('#educationalForm').submit(function(event){
event.preventDefault();
var formData = new FormData($('#educationalForm')[0]);
$.ajax({
url:'{{ route('educational.store') }}',
method: 'POST',
data: formData,
cache:false,
contentType: false,
processData: false,
success:function(data){
const variables = ['grade', 'major', 'end'];
variables.forEach(variable => {
if(data[variable] === null) data[variable] = '';
});
const newRowNum = $('#educationalForm tr').length + 2;
let html = '' +
'<tr>'+
'<td class="fw-normal" id="demo">'+ (newRowNum) +'</td>'+
'<td class="fw-normal">'+data.grade+'</td>'+
'<td class="fw-normal">'+data.major+'</td>'+
'<td class="fw-normal">'+data.end+'</td>'+
'<td>'+
'<form method="post" id="educational-destroy">'+
'#csrf'+
'#method('DELETE')'+
'<div class="btn-group">'+
'<a data-id="'+data.id+'" class="btn btn-info btn-sm" id="educationalEdit" data-bs-toggle="modal" data-bs-target="#educationalModal">ویرایش</a>'+
'<button data-id="'+data.id+'" type="button" class="btn btn-danger btn-sm" id="educationalDestroy">حذف</button>'+
'</div>'+
'</form>'+
'</td>'+
'</tr>';
$('#educationalTable').append(html);
$('#educationalForm').trigger('reset');
},
});
});
showEducationals();
function showEducationals() {
$.get('{{ route('educational.index') }}', function (data) {
$('#educationalTable').html("");
$.each(data, function (key, val) {
const variables = ['grade', 'major', 'end'];
variables.forEach(variable => {
if(val[variable] === null) val[variable] = '';
});
$('#educationalTable').append('<tr>'+
'<td class="fw-normal">'+ (key+1) +'</td>'+
'<td class="fw-normal">'+val.grade+'</td>'+
'<td class="fw-normal">'+val.major+'</td>'+
'<td class="fw-normal">'+val.end+'</td>'+
'<td>'+
'<form method="post" id="educational-destroy">'+
'#csrf'+
'#method('DELETE')'+
'<div class="btn-group">'+
'<a data-id="'+val.id+'" class="btn btn-info btn-sm" id="educationalEdit" data-bs-toggle="modal" data-bs-target="#educationalModal">ویرایش</a>'+
'<button data-id="'+val.id+'" type="button" class="btn btn-danger btn-sm" id="educationalDestroy">حذف</button>'+
'</div>'+
'</form>'+
'</td>'+
'</tr>'
);
});
});
}
$(document).on('click', '#educationalEdit', function(event) {
event.preventDefault();
var id = $(this).data('id');
$.ajax({
type:'get',
url:'/educational/'+id+'/edit',
contentType: "application/json; charset=utf-8",
dataType: "json",
success:function (data) {
console.log(data);
$('#id').val(data.educational.id);
$('#edit_grade').val(data.educational.grade);
$('#edit_major').val(data.educational.major);
$('#edit_avg').val(data.educational.avg);
$("input[name='edit_start']").val(data.educational.start);
$("input[name='edit_end']").val(data.educational.end);
$('#edit_docPlaceName').val(data.educational.docPlaceName);
$('#edit_thesisTitle').val(data.educational.thesisTitle);
$('#edit_docPlaceCountry').val(data.educational.docPlaceCountry);
$('#edit_docPlaceCity').val(data.educational.docPlaceCity);
},
});
});
$(document).on('click', '#educationalUpdate', function(event) {
event.preventDefault();
var id = $('#id').val();
var file = $('#edit_upload_doc').prop('files')[0];
var formData = new FormData($('#educationalFormUpdate')[0]);
formData.append('file', file);
$.ajax({
type: 'POST',
url: '/educational/'+id,
dataType: 'JSON',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (response) {
console.log(response);
$('#educationalModal').modal('hide');
showEducationals();
},
});
});
$(document).on('click', '#educationalDestroy', function(event) {
event.preventDefault();
$.ajax({
url:'educational/'+$(this).data('id'),
type: 'DELETE',
dataType: 'json',
data: {
_token: '{{ csrf_token() }}'
},
success: function(response) {
$('#educationalsTable').html('');
showEducationals();
},
error: function(response) {
console.log(response);
},
});
});
});
</script>
So in general I can get counting right until elements are getting removed. If I got 3 rows I got a count of 1. 2. 3. but if I remove all of them and add again 3 rows I got 4. 5. 6. BUT I need 1. 2. 3. again
You should reset the counter every time you re-render the whole table.
You could move the count to inside your rendering function, but it is not strictly necessary, because jQuery's each function already provides an index (you are naming it key) which you could use instead of count.
Therefore, you can do:
function showEducationals() {
$.get('{{ route('educational.index') }}', function (data) {
$('#educationalTable').html("");
$.each(data, function (key, val) {
const variables = ['grade', 'major', 'end'];
variables.forEach(variable => {
if(val[variable] === null) val[variable] = '';
});
$('#educationalTable').append('<tr>'+
'<td class="fw-normal">'+ (key+1) +'</td>'+ // using key instead of count
Notice I also removed id=demo. This is because you are creating several cells with the id=demo (in '<td class="fw-normal" id="demo">'+count+++'</td>'+) and ideally ids should be unique.
About adding new rows use, instead of i, the number of rows the table actually has:
$('#educationalForm').submit(function(event){
event.preventDefault();
var formData = new FormData($('#educationalForm')[0]);
$.ajax({
url:'{{ route('educational.store') }}',
method: 'POST',
data: formData,
cache:false,
contentType: false,
processData: false,
success:function(data){
const variables = ['grade', 'major', 'end'];
variables.forEach(variable => {
if(data[variable] === null) data[variable] = '';
});
const newRowNum = $('#educationalTable tr').length + 1; // added this
let html = '' +
'<tr>'+
'<td class="fw-normal">'+ (newRowNum) +'</td>'+ // edited this
In addition, you should remove the i and count variables, as they are no longer necessary:
showEducationals();
let i; // remove this
let count = 1; // remove this
function showEducationals() {
// ...
);
i = count // remove this
});

How to Sort XML feed alphabetically

I'm trying to sort an XML feed alphabetically by "LastName" without creating an XSLT template, I have the below code, but it returns and error.
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.ajax({
type: "GET",
url: "https://cors-anywhere.herokuapp.com/https://showcast.com.au/showcast/webservice/actors.aspx?agencyId=&Password=",
dataType: "xml",
success: parseXml
});
});
function parseXml(xml){
$(xml).find("artist").each(function(){
var nx_name = $(this).find("FirstName").text() + ' ' + $(this).find("LastName").text();
var nx_pic = '';
$(this).find("Photos SmallPhotos Photo").each(function(){
if( $(this).find("IsDefault").text() == "True" ){
nx_pic = $(this).find("Url").text();
return false;
}
});
var nxlink = $(this).find("URLlink").text();
var nxhtml = '<div class="nxitem"><div class="nxwrap"><div class="nximgwrap"><img src="'+nx_pic+'"></div></div><br/><span class="nxname">'+nx_name+'</span></div>';
$("#nxdisplay").append(nxhtml);
});
}
</script>

Codeception acceptance test error for save/reset

I am trying to perform acceptance tests for my website using Codeception, and I am experiencing a strange error due to a reset button on the form I am testing. Basically, my test for clicking on 'Save' works only if either the reset button on my form is AFTER the Save button, or if the reset button is left off the form altogether. If the reset button is inserted in the form before the save button, Codeception throws an Unreachable field "reset" error. Here is my Codeception code:
<?php
$I = new WebGuy($scenario);
$I->wantTo('find an employee in the database');
$I->amOnPage('/employees/find/');
$I->fillField('employeeLookup[first_name]', 'Sergi');
$I->click('Save', '#employeeLookup_save');
$I->see('Based on your search for Sergi, the following employees were found:');
$I->see('Remmele');
$I->see('Feb 28 1992');
And here is my HTML (much of it being generated from Symfony2):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Find existing employee</title>
</head>
<body>
<div id="content">
<p>Hello, enter either the first name, or the last name of the employee
you are searching for.</p>
<form name="employeeLookup" method="post" action="">
<div><label for="employeeLookup_first_name" class="required">Name: </label><input type="text" id="employeeLookup_first_name" name="employeeLookup[first_name]" required="required" /></div>
<div><button type="reset" id="employeeLookup_reset" name="employeeLookup[reset]">Reset</button></div>
<div><button type="submit" id="employeeLookup_save" name="employeeLookup[save]">Save</button></div>
<input type="hidden" id="employeeLookup__token" name="employeeLookup[_token]" value="RcpMVTGgB6WhKgDoXXRwmV_l4AFYKWTZko-dnBDhhvM" /></form>
</div>
<div id="sfwdte5d291" class="sf-toolbar" style="display: none"></div><script>/*<![CDATA[*/ Sfjs = (function() { "use strict"; var noop = function() {}, profilerStorageKey = 'sf2/profiler/', request = function(url, onSuccess, onError, payload, options) { var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); options = options || {}; xhr.open(options.method || 'GET', url, true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onreadystatechange = function(state) { if (4 === xhr.readyState && 200 === xhr.status) { (onSuccess || noop)(xhr); } else if (4 === xhr.readyState && xhr.status != 200) { (onError || noop)(xhr); } }; xhr.send(payload || ''); }, hasClass = function(el, klass) { return el.className.match(new RegExp('\\b' + klass + '\\b')); }, removeClass = function(el, klass) { el.className = el.className.replace(new RegExp('\\b' + klass + '\\b'), ' '); }, addClass = function(el, klass) { if (!hasClass(el, klass)) { el.className += " " + klass; } }, getPreference = function(name) { if (!window.localStorage) { return null; } return localStorage.getItem(profilerStorageKey + name); }, setPreference = function(name, value) { if (!window.localStorage) { return null; } localStorage.setItem(profilerStorageKey + name, value); }; return { hasClass: hasClass, removeClass: removeClass, addClass: addClass, getPreference: getPreference, setPreference: setPreference, request: request, load: function(selector, url, onSuccess, onError, options) { var el = document.getElementById(selector); if (el && el.getAttribute('data-sfurl') !== url) { request( url, function(xhr) { el.innerHTML = xhr.responseText; el.setAttribute('data-sfurl', url); removeClass(el, 'loading'); (onSuccess || noop)(xhr, el); }, function(xhr) { (onError || noop)(xhr, el); }, options ); } return this; }, toggle: function(selector, elOn, elOff) { var i, style, tmp = elOn.style.display, el = document.getElementById(selector); elOn.style.display = elOff.style.display; elOff.style.display = tmp; if (el) { el.style.display = 'none' === tmp ? 'none' : 'block'; } return this; } } })();/*]]>*/</script><script>/*<![CDATA[*/ (function () { Sfjs.load( 'sfwdte5d291', '/employees/app_dev.php/_wdt/e5d291', function(xhr, el) { el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none'; if (el.style.display == 'none') { return; } if (Sfjs.getPreference('toolbar/displayState') == 'none') { document.getElementById('sfToolbarMainContent-e5d291').style.display = 'none'; document.getElementById('sfToolbarClearer-e5d291').style.display = 'none'; document.getElementById('sfMiniToolbar-e5d291').style.display = 'block'; } else { document.getElementById('sfToolbarMainContent-e5d291').style.display = 'block'; document.getElementById('sfToolbarClearer-e5d291').style.display = 'block'; document.getElementById('sfMiniToolbar-e5d291').style.display = 'none'; } }, function(xhr) { if (xhr.status !== 0) { confirm('An error occurred while loading the web debug toolbar (' + xhr.status + ': ' + xhr.statusText + ').\n\nDo you want to open the profiler?') && (window.location = '/employees/app_dev.php/_profiler/e5d291'); } } ); })();/*]]>*/</script>
</body>
</html>
Finally, here is the relevant output of the error message from Codeception:
1) Failed to find an employee in the database in FindEmployeeCept.php
Sorry, I couldn't click "Save","#employeeLookup_save":
Behat\Mink\Exception\ElementException: Exception thrown by ((//html/descendant-or-self::*[#id = 'employeeLookup_save'])[1]/.//input[./#type = 'submit' or ./#type = 'image' or ./#type = 'button'][(((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(./#title, 'Save'))] | .//input[./#type = 'image'][contains(./#alt, 'Save')] | .//button[((((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(normalize-space(string(.)), 'Save')) or contains(./#title, 'Save'))] | .//input[./#type = 'image'][contains(./#alt, 'Save')] | .//*[./#role = 'button'][(((./#id = 'Save' or ./#name = 'Save') or contains(./#value, 'Save')) or contains(./#title, 'Save') or contains(normalize-space(string(.)), 'Save'))])[1]
Unreachable field "reset"
Again, if the reset button is rendered after the save button in the HTML, the acceptance tests pass just fine. Also, if the reset button is left off of the form entirely, the acceptance test passes as well. Does anyone have any idea what is causing this?

jQuery - google chrome won't get updated textarea value

I have a textarea with default text 'write comment...'. when a user updates the textarea and clicks 'add comment' Google chrome does not get the new text. heres my code;
function add_comment( token, loader ){
$('textarea.n-c-i').focus(function(){
if( $(this).html() == 'write a comment...' ) {
$(this).html('');
}
});
$('textarea.n-c-i').blur(function(){
if( $(this).html() == '' ) {
$(this).html('write a comment...');
}
});
$(".add-comment").bind("click", function() {
try{
var but = $(this);
var parent = but.parents('.n-w');
var ref = parent.attr("ref");
var comment_box = parent.find('textarea');
var comment = comment_box.val();
alert(comment);
var con_wrap = parent.find('ul.com-box');
var contents = con_wrap .html();
var outa_wrap = parent.find('.n-c-b');
var outa = outa_wrap.html();
var com_box = parent.find('ul.com-box');
var results = parent.find('p.com-result');
results.html(loader);
comment_box.attr("disabled", "disabled");
but.attr("disabled", "disabled");
$.ajax({
type: 'POST', url: './', data: 'add-comment=true&ref=' + encodeURIComponent(ref) + '&com=' + encodeURIComponent(comment) + '&token=' + token + '&aj=true', cache: false, timeout: 7000,
error: function(){ $.fancybox(internal_error, internal_error_fbs); results.html(''); comment_box.removeAttr("disabled"); but.removeAttr("disabled"); },
success: function(html){
auth(html);
if( html != '<span class="error-msg">Error, message could not be posted at this time</span>' ) {
if( con_wrap.length == 0 ) {
outa_wrap.html('<ul class="com-box">' + html + '</ul>' + outa);
outa_wrap.find('li:last').fadeIn();
add_comment( token, loader );
}else{
com_box.html(contents + html);
com_box.find('li:last').fadeIn();
}
}
results.html('');
comment_box.removeAttr("disabled");
but.removeAttr("disabled");
}
});
}catch(err){alert(err);}
return false;
});
}
any help much appreciated.
I believe you should be using val() and not html() on a textarea.
On a side note, for Chrome use the placeholder attribute on the textarea. You won't need a lot of this code.
<textarea placeholder="Write a comment"></textarea>