I've a div which contains a list of clients pulled from Mysql.
On the same page I have a jquery dialog box which pops up to allow a user to add a new client.
What I want to happen is that when the user adds a new client the containing the list reloads so the new client is available.
Is there a way to simply reload the div without using the Load() function as this is causing errors when I redeclare my classes that populate the list ?
Of course. Without looking at your code, your confusion here suggests that you don't understand "Separation of Concerns". Separate the process of getting information from the process of displaying that information. When the user enters new information, add that to javascript array or object of information you got from the server and also send that off to the server to be updated in the database. Then run the display function again using the updated information to include the new information. Ideally, the display process will use existing markup if it can, rather than deleting it all and recreating it all just to add one item. Here's a very basic example (click here). Ideally, you would take this concept and expand on it to make it optimally efficient and organized.
Here's the sample code from my jsbin. Please keep in mind this is just to get you started.
var info = [1,2,3,4,5]; //this is what you got from your ajax call to the server
function render(element, info) {
//this is a lazy system that recreates/replaces all the markup each time. I suggest doing this more efficiently, but that is work for you to do :)
var frag = document.createDocumentFragment();
var len = info.length;
for (var i=0; i<len; ++i) {
var p = document.createElement('p');
p.textContent = info[i];
frag.appendChild(p);
}
element.innerHTML = '';
element.appendChild(frag);
}
var targetElem = document.getElementById('targetElem');
render(targetElem, info);
var addButton = document.getElementById('add');
var input = document.getElementById('infoInput');
addButton.addEventListener('click', function() {
info.push(input.value); //update the information
render(targetElem, info); //render the updated information
});
Either of these should give you success.
success: function(userinfos) {
$("#users").append($('<tr><td>'+userinfos+'</td></tr>'))
display_message("user added");
}
$.ajax({
type: "GET",
url: "ht.tp://127.0.0.1:8000/result/?age="+ ageData +"&occasion="+
occasionData +"&relationship="+ forData +"#",
success: function (response) {
$("#testDIV").html(response);
}
});
Related
I am working on an AJAX cart system where the sub total will automatically update when the quantity changes. My solution is every time the input changes, post it to the current page (cart page) then reload the div that displays the sub total. However, I don't know how to do this with pure JavaScript, and I haven't found any reference yet.
This is my function for the above algorithm:
var _rangeInput = document.querySelectorAll('.ranum'), _upAload = document.getElementsByClassName('upAload');
var _frmData = {};
for (var i = 0; i < _rangeInput.length; i ++) {
_rangeInput[i].addEventListener('change', function(){
_frmData[this.name] = this.value;
ajaxFormValidate({
type: 'POST',
url: location.href,
method: true,
sendItem: _frmData,
success: function(response) {
//reload here
}
});
}, false);
}
Code explaination:
First, get the inputs and divs that need to be processed.
Loop through all of the inputs and get their values and names.
I have written an AJAX function for my self, you can look above.
Is there anyway to do this with pure JavaScript?
I can't use JavaScript methods or functions to change the content since I am sending the request to the same page, as a result, response here will have the value of the whole document.
Also, this is how the system works:
First, the user changes the quantity they want
AJAX sends request to the same page
The page changes the information based on the request
AJAX receives the request, and refreshes/reloads the specific div
Simply set the innerHTML of your sub total div with the response data.
document.getElementById("sub-total").innerHTML = response.value; //Whatever value you get in response
It sounds like you're actually asking how to get a single element out of an AJAX response.
You can do that by parsing the response into a temporary element, then finding the element you need within it:
const holder = document.createElement('div');
holder.innerHTML = response;
const myElement = holder.querySelector('some selector');
I made a board application and implementing comment function using django framework.
I use jquery & ajax to GET and POST comments.
Now I want to add Edit and Delete function.
As you can see in image, there is edit and delete button. What I'm trying to do is to show those buttons only for the comment that current user had posted.
This is part of my ajax getting comments from my comments API.
$.ajax({
url: commentURL,
type: "GET",
success: function(data){
var numOfComments = data.length;
$(commentCountElement).html(numOfComments);
data.forEach(function(comment){
/* Get data from API results */
var commentUsername = comment.author_name;
var commentContent = comment.content;
var commentCreatedAt = comment.created_at;
var commentID = comment.id;
/* Create html li */
var listElement = $("<li>").addClass("comment-box");
/* Create div comment-meta */
var commentMetaDiv = $("<div>").addClass("comment-meta");
$(commentMetaDiv).append($("<span>").text(commentUsername));
$(commentMetaDiv).append($("<span>").addClass("date").text(commentCreatedAt));
/* Create div comment-content */
var commentContentDiv = $("<div>").addClass("comment-content");
$(commentContentDiv).text(commentContent);
/* Append */
$(listElement).append(commentMetaDiv);
$(listElement).append(commentContentDiv);
$(commentUnorderedListElement).append(listElement);
});
},
error: function(data){
console.log(textStatus);
return false;
}
});
Now, I have to compare current login user with comment.author_name so that I can add button depending on that result. But I have no idea how I can get current user's infos in js.
Need your help. thanks
I assume you are using session authentication.
You can do it in several ways.
First, you can add an extra field in your comments API by doing something like this:
comments['editable'] = request.user.user_name == comment.author_name
If it is True, user can edit the comment and vice versa. I believe this is a better way.
Second way is directly in your script get access to django user and compare there:
<script>
var editable = comment.author_name == {{ request.user.user_name }}
</script>
This is not a good approach. Because you are mixing django variable with jquery! If your script is in another file, it won't work at all.
So, I would go with the first way.
Hope it helps
In your templates:
<script>
var reply_name = {{ request.user.user_name }};
get_comment(repay_name) #call what you want using js
</script>
I’ve successfully implemented routing and hashing with crossroadsJS and hasherJS on a SPA I’m working on. The data I’m loading from a REST API is entirely event based. This works fine for navigating through the website with click based events. However, I want to implement the ability to type in a URL (or refresh the current view) and load the data corresponding to that URL. I wrote a method like this:
// app.js
app.helpers = {
routeMagic: function (prop, clicked, type, el) {
var parser = document.createElement('a'); // setup parsing
parser.href = hasher.getURL(); // use hasher's .getURL() to find current URL
var splitURL = parser.hash.split('/')[2]; // split at second / ... example: /conditions/annual-wellness-exam => annual-wellness-exam
propArr = []; // set up array to store name property
for (var i=0, len=prop.length; i<len; i++) {
propArr.push(prop[i].name.replace(/,/g, "").replace(/\//g, "").replace(/[()]/g, "").replace(/\s+/g, "-").toLowerCase());
}
$(el).each(function () { // target li ... example ‘.returned-list li’
var val = $(this);
val.id = propArr; // append name to li id
var id = $(this).attr('id');
// this is only executing on click event, need it to execute on refresh or typing in URL
if (splitURL === id) { // find a match
console.log('match found');
clicked = val.children().attr('data-id'); // determine where to route the page to based off data-id
return false;
}
});
type(clicked); // init crossroads routing
}
};
Which would be called like so:
// routes.js
conResultsRoute = crossroads.addRoute('conditions/{name}', function () {
app.helpers.routeMagic(cache.lists.conditions, cache.justClickedCondition, api.endpoints.condition, '.returned-list li');
});
For this example, when I click on a ‘conditions’ link from a list of conditions, the expected results are returned on the following route. However, if I try to type in the same URL, I get a list back of all the data stored in the CMS rather than my filtered list like when I click through the app. I think the problem stems from not being able to target my $(el).each() on page load since it’s held in a different template, or possibly I have to reload my API calls every time I type in a URL. I imagine this isn’t enough data for someone to troubleshoot, so feel free to ask me more questions or check out a live (in development) version here
If you’re visiting the website, try a flow like this:
Conditions (main nav) -> Annual Wellness Exam -> Refresh or hit enter in URL bar
what I am trying to achieve is to AJAX a load of client's data into a page (this works), I then have a company ID in one of the fields brought in. I need to cross check this with a different company table (same database) to replace the company ID on the page with the name instead.
To get this I have set a global javascript variable to blank then fired off the main AJAX request getting all the initial client data then within that parsing loop (client side) I need to fire off a function which will check against the companies table to get the name. My current problem is that the global variable is not being set to the 2nd AJAX result. Here is my code:
var nameresult = "";
function namecheck(id){
var request = new Ajax().sendRequest
('../company_check.php',
{ method: 'GET',
parameters: 'id=' + id,
callback: namecheckReceived }
);
}
function namecheckReceived(xmlHTTP){
var n_data = JSON.parse(xmlHTTP.responseText);
nameresult = n_data[0].name;
}
function client_call(){
var request = new Ajax().sendRequest
('../client_data.php',
{ method: 'GET',
callback: searchReceived }
);
}
function searchReceived(xmlHTTP){
var data = JSON.parse(xmlHTTP.responseText);
for(var i=0; i<data.length; i++)
{
namecheck(data[i].company_id);
/////spit out all the data in a readable format //////
}
}
Notes:
Only one result will be received from the company_check.php hence no
loop in the namecheckRecieved() function.
No errors in the JS console.
The nameresult variable stays as blank and is never
changed, if I alert(nameresult) within the namecheckRecieved()
function it spits out what I want so why is it not changing the
global variable with each loop of the searchRecieved() function?
I'm going to delete all my previous comment and say that you only need one ajax call. And everything should be done on server side. That means get the company Id, and use that to get the name of the company then pass everything back to the client side. From the look of it you are doing A LOT of call backs to the server to get every company name when you could have just done that on your first visit to the server. This way you do not need to worry about doing two ajax call Although from the look of it your doing more than 2 calls, depending on the length of data
Try this
function namecheckReceived(xmlHTTP){
var n_data = JSON.parse(xmlHTTP.responseText);
nameresult = n_data[0].name;
client_call();
}
This is a followup to a question I asked yesterday on the Google Apps Script Office Hours Hangout.
The goal of my final script is to create an election process for student elections at the high school where I work using Google Forms. The script has three parts: 1) Create Unique "Voting IDs" (a random 6-digit code) 2) Merge the student data (Name, Homeroom, & Voting ID) on with a template document that will create specific voting instruction for each student. (i.e. an old-fashioned mail merge) 3) Verify the results by checking Voting ID's and removing duplicate votes.
The part of the script that I am having trouble with is the student data merge (step 2). The first dataset is the only one that works. The rest show up as "DocumentBodySection". I have a feeling it is either how I am copying the text from the Document Template or how I am adding the text to the new document.
Spreadsheet w/ Data: https://docs.google.com/spreadsheet/ccc?key=0AierVcXWELCudFI1LU10RnlIVHNsUm11a0dDWEV6M1E
Document Template: (see followup comment for url)
Document Created by Script: https://docs.google.com/document/d/12r2D9SpIVmQYVaasMyMWKjHz6q-ZZyIMEBGHTwlQct8/edit
//Get Settings & Data
ss = SpreadsheetApp.getActiveSpreadsheet();
source_sheet = ss.getSheetByName("Student Data");
settings_sheet = ss.getSheetByName("SETTINGS");
results_column = settings_sheet.getRange("B19").getValue();
source_column = settings_sheet.getRange("B18").getValue();
source_lastrow = source_sheet.getLastRow();
docTemplateID = settings_sheet.getRange("B13").getValue();
docCopyName = settings_sheet.getRange("B14").getValue();
//Merge Student Data with Document
function SendDataMerge () {
// Open docTemplate and Copy Contents to entryTemplate
var docTemplate = DocumentApp.openById(docTemplateID);
var entryTemplate = docTemplate.getActiveSection();
docTemplate.saveAndClose();
// Make a NEW copy of docTemplate
var docTemplate = DocsList.getFileById(docTemplateID);
var docCopy = DocsList.copy(docTemplate, docCopyName);
var docCopyID = docCopy.getId();
// Create Array of Student Data (First, Last, Grouping, VID)
var data = source_sheet.getRange("A2:D"+source_lastrow).getValues();
// Open docCopy for Editing & Clear Contents
var doc = DocumentApp.openById(docCopyID);
var docText = doc.editAsText();
// Run through Student Data
for(var i=0; i<5 /*data.length*/; i++) { //For testing, limit this to 5 entries
var lastName = data[i][0];
var firstName = data[i][1];
var grouping = data[i][2];
var vid = data[i][3];
docText.replaceText('keyLastName', lastName);
docText.replaceText('keyFirstName', firstName);
docText.replaceText('keyGrouping', grouping);
docText.replaceText('keyVID', vid);
docText.appendText('\n*** Appended Text (End of entry) ***');
docText.appendText(entryTemplate);
}
// Save and Close
doc.saveAndClose();
}
I worked around this issue by creating a copy of the template, doing the text replacement and then appending the template elements from the original document into the copy. In particular, I used: var copyTables = templateDoc.getTables(); to fetch and store the tables (as all of my template data was contained in a table) and copyDoc.appendTable(copyTables[0].copy() ); to append the copy (the .copy() at the end seems to work the real magic). This provides the flexibility of updating the template in the friendly Documents interface without having to see a programmer.
I think the problem is with this line:
docText.appendText(entryTemplate);
The variable entryTemplate holds a DocumentBodySection, which is why you are seeing that in the output. If you are trying to append another copy of the original template text you'll need to store that before you enter the loop.
I agree with Eric that appendText(entryTemplate) isn't going to do what you want it to do.
Since you're trying to create one large document with all the students, using a "template" and replacing the text isn't going to work well. I'd suggest instead, creating the "template" in code using the api calls that produce the formatting you want. Then it makes it simple to keep appending new pages of student instructions. Although I think you may run into slowness when the document gets large... I don't know how many students you have.