I'm constructing quite a big <span> - element that is being generated dynamically in code.
var span = '<span id="' + dayNumber + '/' + Number(currentMonth + 1) + "/" + Number(date.getFullYear()) + '" class="day ' + respons[0] + '" ng-click="gotoDetail($event)" style="height:' + screenHeigt + 'px; display:table;"><p style="display:table-cell; vertical-align:middle;">' + dayNumber + ' </p></span>';
As you can see, the id consist of a date-string. Via the ng-click-element I would like to pass the id to the gotoDetail($event)-function. When I'm inspecting the parameter of that function, I see however that $event.target.id is empty...
Following code is an older version and does work:
var span = '<span id="' + dayNumber + '/' + currentMonth + '" class="day ' + respons[0] + ' ' + lastMonth + ' " ng-click="gotoDetail($event)">' + dayNumber + '</span>' + string;
I really don't know what I'm doing wrong in the first example...
If I check my html in the chrome-console, there's nothing wrong with the id, the ng-click, or other attributes...
Someone who has an anwser?
EDIT: Code can be found here: https://gist.github.com/anonymous/c29798e0d46f40dcfe69
Related
I managed to check the file extension type and detect fake files but the problem that I'm facing now is after the alert message(alert that the image is fake) the details of the file are still being displayed in the table. How to remove the details from being display in the table after the alert message.
https://i.stack.imgur.com/9a2x4.png
Here's the code of my work:
https://jsfiddle.net/auwhk7v1/1/
Here's one of the code that displaying details of the files:
vpb_added_files_displayer += '<tr id="add_fileID' + vpb_file_id + '" class="' + new_classc + '"><td>' + vpb_file_icon + ' ' + this.vpb_files[i].name.substring(0, 40) + '</td><td><span id="uploading_' + vpb_file_id + '"><span style=color:blue;>Ready</span></span></td><td>' + vpb_actual_fileSize + '</td><td><select class="form-control required type_doc_'+vpb_file_id+'" id="type_doc" name="type_doc" value="" title="File Type for document/photo" onchange="get_doc_type(this.value, \'' + vpb_file_id + '\')" required/><option value="0">Please Select</option>'+load_checklist('type_doc', vpb_file_id)+'</select></td><td><span id="remove' + vpb_file_id + '"><span class="vpb_files_remove_left_inner" onclick="vpb_remove_this_file(\'' + vpb_file_id + '\',\'' + this.vpb_files[i].name + '\');">Remove</span></span></td></tr></div>';
vpb_added_files_displayer2 += '<tr id="add_fileID' + vpb_file_id + '" class="' + new_classc + '"><td>' + vpb_file_icon + ' ' + this.vpb_files[i].name.substring(0, 40) + '</td><td><span id="uploading_' + vpb_file_id + '"><span style=color:blue;>Ready</span></span></td><td>' + vpb_actual_fileSize + '</td><td><select class="form-control required type_doc2_'+vpb_file_id+'" id="type_doc2" name="type_doc2" value="" title="File Type for photos" onchange="get_doc_type(this.value, \'' + vpb_file_id + '\')" required/><option value="0">Please Select</option>'+load_checklist('type_doc2', vpb_file_id)+'</select></td><td><span id="remove' + vpb_file_id + '"><span class="vpb_files_remove_left_inner" onclick="vpb_remove_this_file(\'' + vpb_file_id + '\',\'' + this.vpb_files[i].name + '\');">Remove</span></span></td></tr></div>';
}
}
//Display browsed files on the screen to the user who wants to upload them
if (this.vpb_settings.vpb_form_id == "myForm") {
$("#add_files").append(vpb_added_files_displayer);
$("#added_class").val(new_classc);
// load_checklist('type_doc');
} else if (this.vpb_settings.vpb_form_id == "myForm2") {
$("#add_files2").append(vpb_added_files_displayer2);
$("#added_class").val(new_classc);
// load_checklist('type_doc2');
I used one of the codes that I search in stack overflow:
How to check file MIME type with javascript before upload?
I've tried files.value='' but still the details are displayed in my table. Can anyone solve this for me? Thanks in advance.
I'm trying to create a simple class directory for my kid's class. I have a Array of students in JSON format and wrote an AJAX call for the kids' names, and parents information. But some don't have two parents or two sets of contact information? I have tried "if (studentData !== null) {
show the data} but that doesn't work.
function showStudents() {
var currentURL = window.location.origin;
$.ajax({ url: currentURL + '/api/students', method: 'GET'})
.then(function(studentData) {
console.log("------------------------------------");
console.log("URL: " + currentURL + "/api/students");
console.log("------------------------------------");
// Here we then log the NYTData to console, where it will show up as an object.
console.log(studentData);
console.log("------------------------------------");
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
studentSection.addClass('card');
studentSection.attr('id', 'studentCard-' + i);
studentSection.attr('style', 'width:25rem');
$('#studentSection').append(studentSection);
$('#studentCard-' + i ).append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>');
$('#studentCard-' + i ).append('<ul class="list-group list-group-flush>');
$('#studentCard-' + i ).append('<li class="list-group-item"><h5>Parent(s):</h5>' + studentData[i].parent1 + ' & ' + studentData[i].parent2 +' </li>');
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
$('#studentCard-' + i ).append('</ul>');
$('#studentCard-' + i ).append('</div>');
}
});
}
It sounds like it's the parent1 or parent2 properties that might not exist, and the contact1 or contact2 properties that might not exist. It doesn't make sense to test if the entire response is null - just check those properties instead. For example:
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
studentSection.addClass('card');
studentSection.attr('id', 'studentCard-' + i);
studentSection.attr('style', 'width:25rem');
$('#studentSection').append(studentSection);
$('#studentCard-' + i ).append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>');
$('#studentCard-' + i ).append('<ul class="list-group list-group-flush>');
// Start of changes
const parentStr = [studentData[i].parent1, studentData[i].parent2].filter(Boolean).join(' & ');
$('#studentCard-' + i ).append('<li class="list-group-item"><h5>Parent(s):</h5>' + parentStr +' </li>');
if (studentData[i].contact1) {
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
}
if (studentData[i].contact2) {
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
}
// End of changes
$('#studentCard-' + i ).append('</ul>');
$('#studentCard-' + i ).append('</div>');
}
Your script structure could be improved too - unless each card's id is particularly important, it would make more sense to use a class instead of unique ids for every single element, or perhaps to leave it off entirely if you're only using it to select the newly created container. You already have a reference to the element you just created with studentSection, so just reference that variable again. You can also use method chaining to reduce your syntax noise:
CSS:
.card {
width: 25rem;
}
(that will keep you from having to manually set the width of each created element in your JS)
JS loop:
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
$('#studentSection').append(studentSection);
const parentStr = [studentData[i].parent1, studentData[i].parent2].filter(Boolean).join(' & ');
studentSection.addClass('card')
.append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>')
.append('<ul class="list-group list-group-flush>')
.append('<li class="list-group-item"><h5>Parent(s):</h5>' + parentStr +' </li>');
if (studentData[i].contact1) {
studentSection.append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
}
if (studentData[i].contact2) {
studentSection.append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
}
studentSection.append('</ul>');
.append('</div>');
}
(Or, even better, use template literals instead)
There seems to be a syntax error that I can't seem to solve in JavaScript.
var newRow = jQuery('<tr><td><div align="center"><input type="checkbox"class="case" onclick="showhide('display','')"/></div></td><td>' + daterecorded + '</td><td>' + arrivaltime + '</td><td>' + departuretime + '</td><td>9h 30min</td><td>' + specialreason + '</td></tr>');
jQuery('table.manual').append(newRow);
});
This part: onclick="showhide('display','')" has been giving me syntax errors.
I have tried this onclick="showhide(' + display + ' ' + ,''+ ')"
and get myself confused. couldn't seem to get the syntax right. any help please?
var newRow = jQuery('<tr><td><div align="center"><input type="checkbox" class="case" onclick="showhide(\'display\',\'\')"/></div></td><td>' + daterecorded + '</td><td>' + arrivaltime + '</td><td>' + departuretime + '</td><td>9h 30min</td><td>' + specialreason + '</td></tr>');
jQuery('table.manual').append(newRow);
});
You just need to escape the two ' around display.
or you can bind event after creating row
var newRow = jQuery('<tr><td><div align="center"><input type="checkbox" class="case" /></div></td><td>' + daterecorded + '</td><td>' + arrivaltime + '</td><td>' + departuretime + '</td><td>9h 30min</td><td>' + specialreason + '</td></tr>');
jQuery('table.manual').append(newRow);
newRow.find(".case").click(function () { showHide('display', ''); });
});
dont have to mind escaping and much better to read.
I am dynamically adding <script> tags with javascript & jQuery into my html file whenever a button is pushed. Everything gets added in correctly but only one of the two .click jQuery action functions is working. I can't seem to figure out why. No errors in console. I made sure i used \' and \" in the correct places.
$('#classBox').append('<tr id=\"' + tempCHAR + tempNUM + '\">'
+ '<td>'
+ '<i id=\"' + tempCHAR + tempNUM + '\" class=\"icon-remove-sign\">'
+ '</i> '
+ '<a id=\"' + tempCHAR + tempNUM + '\"" href=\"https://cms.psu.edu/section/default.asp?id=' + urlHOLDER + '\" target="framehidden">'
+ tempYEAR + ': ' + tempCHAR + tempNUM + ', Section ' + tempSEC
+ '</a>'
+ '</td>'
+ '</tr>'
+ '<script>'
+ '$(\'#' + tempCHAR + tempNUM + '\').click(function() {'
+ '$(\'tr\').remove(\'tr#' + tempCHAR + tempNUM + '\');'
+ '});'
+ '$(\'a#\'' + tempCHAR + tempNUM + ').click(function() {'
+ '$(\'#framehidden\').attr(\'src\', $(\'a\', this).attr(\'href\')));'
+ '});'
+ '</script>');
The indents are just for me to more easily read what I'm doing. That wouldn't be the problem would it?
If thats too impossible to read then here it is in normal view.
$('a#'IST130).click(function() {
$('#framehidden').attr('src', $('a', this).attr('href')));
});
$('#IST130').click(function() {
$('tr').remove('tr#IST130');
});
I have like 30 other .click functions that all work perfectly but I just cannot figure out what is going wrong here. Any hints?
Since .append() is instant (ie. synchronous), there is absolutely no need to put that stuff in a <script> tag. Instead, try this:
$('#classBox').append('<tr id=\"' + tempCHAR + tempNUM + '\">'
+ '<td>'
+ '<i id=\"' + tempCHAR + tempNUM + '\" class=\"icon-remove-sign\">'
+ '</i> '
+ '<a id=\"' + tempCHAR + tempNUM + '\"" href=\"https://cms.psu.edu/section/default.asp?id=' + urlHOLDER + '\" target="framehidden">'
+ tempYEAR + ': ' + tempCHAR + tempNUM + ', Section ' + tempSEC
+ '</a>'
+ '</td>'
+ '</tr>');
$('#' + tempCHAR + tempNUM).click(function() {
$('tr').remove('tr#' + tempCHAR + tempNUM);
});
$('a#' + tempCHAR + tempNUM).click(function() {
$('#framehidden').attr('src', $('a', this).attr('href')));
});
That being said, your code is HORRIBLY invalid. IDs MUST be unique. I'll leave you to fix that in whatever way works best for you, but yeah.
Your error (or at least one of them) is on this line:
+ '$(\'a#\'' + tempCHAR + tempNUM + ').click(function() {'
Just have an extra single quote there that needs to be moved to the end of the $() block:
+ '$(\'a#' + tempCHAR + tempNUM + '\').click(function() {'
In your example at the end you have $('a#'IST130). Pretty sure that should read $('a#IST130)`
To correct it, change the generation for that ID to:
'$(\'a#' + tempCHAR + tempNUM + '\')...
Additionally, since you are dynamically adding the elements, their click events may not bind properly, depending on exactly when your code is executing.
You can use jquery on to set a bind for the events on a permanent element. In this case #classBox looks like a good bet. It might look something like this (where this would be inside a normal script block and outside of your dynamic stuff:
$('#classBox').on('click','a',function () {
$('#framehidden').attr('src', $('a', this).attr('href')));
});
$('#classBox').on('click',function () {
$(this).closest('tr').remove();
});
Note: Completely untested - intended as a guide!
After you fix the syntax errors, also be sure the click events aren't being attached before the append() code has run.
I can't tell which order the code runs in the actual page - if you're appending the elements before the click events are being attached, the elements may not exist yet. You can use jQuery's delegate method to ensure the events are called for all elements, no matter when they're appended to the DOM.
For example:
$('body').delegate('.anchorClassName', 'click', function(e){});
I am working on preparing some dynamic html with jquery and json object. but the problem is that when my json object has around 1500 rows it takes ages to load.
is there a way to load the thing faster.
Some code.
$(jQuery.each(jsonObject.AvailableColumns, function (i, l) {
if (type == "manual") {
innerList1 += '<li newText="" valueFormat="' + l.ValueFormat + '" scaleID="' + l.ScaleID + '" scaleType="' + l.ScaleType + '" hasWeights="' + l.HasWeights + '" customColumnType="' + l.CustomColumnType + '" class="" id="li_' + controlId + '"><span id="span_' + controlId + '" title = "' + l.QuestionText + '">' + getDisplayString(l.QuestionText) + '</span><a class="actionLeft"></a></li>';
}
else if (type = "exportall") {
innerList2 += CreateLiWithSpans('li_' + controlId, l.QuestionText, true, false, l.ScaleID, l.ScaleType, l.HasWeights, l.CustomColumnType, l.ValueFormat);
}
controlId++;
}));
$("#itemList").html(innerlist1);
EDIT : createliwithspan method
function CreateLiWithSpans(id, html, isLeft, isAddAll, scaleID, scaleType, hasWeights, customColumnType, valueFormat, newText) {
var ancClass = isLeft ? 'actionRight' : 'actionLeft';
var liObject = "";
if (newText == null) {
newText = "";
}
if (isLeft) {
liObject = '<li newtext="' + newText + '" valueFormat="' + valueFormat + '" scaleID="' + scaleID + '" scaleType="' + scaleType + '" hasWeights="' + hasWeights + '" customColumnType="' + customColumnType + '" class="" id="' + id + '"><span id="span_' + id + '" title = "' + html + '">' + getDisplayString(html) + '</span><span style="margin:0 10px 0 20px;pagging:0"><input title = "' + (newText == "" ? html : newText) + '" type="text" id="' + id + 'displayText" value="' + (newText == "" ? html : newText) + '" /><span style="color:Red; width:100%;" id="' + id + 'displayTextError"></span></span><span style="float:left">' + CreateDropDown('ddl_' + id, valueFormat, hasWeights) + '</span><a class="' + ancClass + '"></a></li>';
}
else {
liObject = '<li newtext="' + newText + '" valueFormat="' + valueFormat + '" scaleID="' + scaleID + '" scaleType="' + scaleType + '" hasWeights="' + hasWeights + '" customColumnType="' + customColumnType + '" class="" id="' + id + '"><span id="span_' + id + '" title = "' + html + '">' + getDisplayString(html) + '</span><a class="' + ancClass + '"></a></li>';
}
return liObject;
}
You can use for loop instead of jQuery.each, that will be faster. Store the itemCount before the loop, and use that:
itemCount = jsonData.items.length;
for(var i = 0; i < itemCount; i++ ) {
...
You can also use use an array instead of string concatenation, like so:
var innerList = [];
... // inside the loop
innerList.push(CreateLiWithSpans('li_' + controlId, l.QuestionText, true, false, l.ScaleID, l.ScaleType, l.HasWeights, l.CustomColumnType, l.ValueFormat));
... // after the loop
$("#itemList").html(innerList.join(''));
This will be faster in IE, I'm not sure about other js engines.
These two methods will not make a significant difference, so you should try implementing a client side pagination from json. (Not by hiding and showing divs, by rendering only visible page into the DOM).
Instead of waiting for the loop to end to append your data, why not actively append the data as you process it. This will allow the user to get immediate feedback instead of waiting for the whole thing to process. Other than this, I'd stick with my original comment to page the data.
$(jQuery.each(jsonObject.AvailableColumns, function (i, l) {
if (type == "manual") {
$("#itemList").append( '<li newText="" valueFormat="' + l.ValueFormat + '" scaleID="' + l.ScaleID + '" scaleType="' + l.ScaleType + '" hasWeights="' + l.HasWeights + '" customColumnType="' + l.CustomColumnType + '" class="" id="li_' + controlId + '"><span id="span_' + controlId + '" title = "' + l.QuestionText + '">' + getDisplayString(l.QuestionText) + '</span><a class="actionLeft"></a></li>');
}
else if (type = "exportall") {
$("#itemList2").append(CreateLiWithSpans('li_' + controlId, l.QuestionText, true, false, l.ScaleID, l.ScaleType, l.HasWeights, l.CustomColumnType, l.ValueFormat));
}
controlId++;
}));
Try replacing jQuery.each with a plain old for...in loop. Using jQuery.each adds overhead that you don't need.
Don't concatenate strings inside your loop. Instead, .push them onto an array variable and use .join('') to build the string all at once at the end.
You may need to eliminate CreateLiWithSpans as a separate function in order to fully implement (2).
Changing from using jQuery.each to a standard javascript for loop should speed it up a bit. Make sure that you save the length to a variable like this though:
for(var i = 0, len = jsonObject.AvailableColumns.length; i < len; i++){
var l = jsonObject.AvailableColumns[i];
// Continue with rest of code
}
Probably won't be a huge increase but every little helps.
Also try lowering the number of function calls you make as these have added overhead (not usually an issue, but in a large loop it can help). Unless the code is shared between functions try doing it inline and see how much that speeds it up.