Duplicate of richText field in Notes Document - custom-controls

I have a file uploader on some of my XPages. It works so well, but there's one profound disadvantage of using it. In some cases, it creates 2 or 3 or 4 or n of duplicates of the same field inside the document. And it only happens if I try to upload a single file (or a set of files) and do the same right after it. Sometimes this happens after I delete one file and upload more. The document's fields look like this after saving. I have no idea about the reason why this happens.
Initially I thought that it could be because I've forgotten to put doc_source.save(); statement in the delete button. But it didn't turned out to be the reason.
The code of the CC is below
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div id="${javascript:compositeData.ID+'refresh'}">
<xp:table>
<xp:this.rendered><![CDATA[#{javascript:currentDocument.isEditable() && (!context.getUserAgent().isIE(6,9))
}]]></xp:this.rendered>
<xp:tr>
<xp:td id="td1" styleClass="doc_field_select">
<xp:text escape="false" id="cf_add">
<xp:this.value><![CDATA[#{javascript:return(texticon('plus-5-icon',25,25,'Add files',false))
}]]></xp:this.value>
</xp:text>
<xp:eventHandler event="onclick" submit="false"
disableValidators="true">
<xp:this.script><![CDATA[document.getElementById("#{javascript:compositeData.ID+'_files_input'}").click();]]></xp:this.script>
</xp:eventHandler>
</xp:td>
<xp:td styleClass="doc_field_select" id="td2">
<xp:text escape="false" id="cf_deleteall">
<xp:this.value><![CDATA[#{javascript:return(texticon('x-mark-4-icon',25,25,'Delete all',false))
}]]></xp:this.value>
</xp:text>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" disableValidators="true">
<xp:this.script><![CDATA[var id='#{javascript:
getClientId(compositeData.ID+"_files_upload")}';
var tst=document.getElementById(id);
tst.value='';]]></xp:this.script>
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
var doc:NotesDocument=doc_source.getDocument(true);
if (doc==null)
{
return(null);
}
if (!doc.hasItem(compositeData.FieldName))
{
return(null);
}
var rit1:NotesRichTextItem=doc.getFirstItem(compositeData.FieldName);
if (rit1==null)
{
return(null);
}
try
{
var arr=rit1.getEmbeddedObjects();
}
catch(e)
{
return(null);
}
for(var i = 0; i < arr.length; i++)
{
doc_source.removeAttachment(compositeData.FieldName, arr[i].getName());
}
return;
var doc:NotesDocument=doc_source.getDocument(true);
var rit:NotesRichTextItem=doc.getFirstItem(compositeData.FieldName);
if (rit==null)
{
return('');
}
var arr=rit.getEmbeddedObjects()
if (arr==null)
{
return('');
}
res=[]
for (var i = 0; i < arr.length; i++)
{
var att:NotesEmbeddedObject=arr[i];
//res.push(att.getName())
arr[i].remove();
}
//doc.save()
doc=doc_source.getDocument(true);
print('has RichText');
print(doc.hasItem(compositeData.FieldName));
return;}]]></xp:this.script>
</xp:executeScript>
<xp:saveDocument></xp:saveDocument>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:td>
</xp:tr>
</xp:table>
<div style="height:0px;overflow:hidden">
<input type="file"
id="${javascript:compositeData.ID+'_files_input'}"
onchange="${javascript:
var urlToUpload = '\''+database.getHttpURL()+ database.getFilePath().replace(/\\/g,'/') + view.getPageName() + '\'';
var filesInput = '\'' + compositeData.ID + '_files_input' + '\'';
var filesUpload = '\'' + compositeData.ID + '_files_upload' + '\'';
var filesButton = '\'' + compositeData.ID + '_files_button' + '\'';
var filesProgress = '\'' + compositeData.ID + '_files_progress' + '\'';
return 'files_onchange(' + urlToUpload + ',' + filesInput + ',' + filesUpload + ',' + filesButton + ',' + filesProgress + ')';
}"
multiple="true" uploadOnSelect="true" name="uploadedfile" />
<xp:fileUpload
id="${javascript:compositeData.ID+'_files_upload'}"
useUploadname="true">
<xp:this.value><![CDATA[#{doc_source[compositeData.FieldName]}]]></xp:this.value>
</xp:fileUpload>
<xp:button value="Refresh"
id="${javascript:compositeData.ID+'_files_button'}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" disableValidators="true"
refreshId="${javascript:compositeData.ID+'refresh'}">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument></xp:saveDocument>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
if (compositeData.postUpload!=null)
{
compositeData.postUpload.getScript().invoke(facesContext, null)
}}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</div>
<xp:repeat id="${javascript:compositeData.ID+'_files_repeat'}"
rows="30" var="rowData" indexVar="rowIndex">
<xp:this.value><![CDATA[#{javascript:
try
{
var doc:NotesDocument=doc_source.getDocument(true);
}
catch(e)
{
var oss=new OsnovaSession();
}
if (doc==null)
{
return(null);
}
if (!doc.hasItem(compositeData.FieldName))
{
return(null);
}
var rit1:NotesRichTextItem=doc.getFirstItem(compositeData.FieldName);
if (rit1==null)
{
return(null);
}
try
{
var arr=rit1.getEmbeddedObjects()
}
catch(e)
{
return(null);
}
return(arr)
}]]></xp:this.value>
<xp:table>
<xp:tr>
<xp:td styleClass="doc_field_select" id="td4">
<xp:text escape="false" id="cf_file">
<xp:this.value><![CDATA[#{javascript:
if (rowData==null)
{
return('');
}
var siz=(rowData.getFileSize()/1024).toFixed(1);
siz=siz.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ');
return(texticon('download-9-icon',compositeData.IconSize,compositeData.IconSize,rowData.getName()+' ('+siz+' KB) ',false));
}]]></xp:this.value>
<xp:this.style><![CDATA[#{javascript:
if(compositeData.IconColor==null)
{
return('')
}
else
{
return('fill:'+compositeData.IconColor+';')
}}]]></xp:this.style>
</xp:text>
<xp:link escape="true" text="Link"
id="link_test" target="_blank" style="display:none">
<xp:this.value><![CDATA[#{javascript:var oss=new OsnovaSession()
try
{
var db:NotesDatabase=session.getDatabase(null,null);
db.openByReplicaID(session.getCurrentDatabase().getServer(),compositeData.ReplicaID);
var doc=db.getDocumentByUNID(compositeData.DocumentUNID);
}
catch(e)
{
var doc=null;
}
if(doc==null)
{
var doc:NotesDocument=doc_source.getDocument();
var db=database;
}
if (doc==null)
{
return(null);
}
//http(s)://[yourserver]/[application.nsf]/[viewname|0]/[UNID| ViewKey]/$File/[AttachmentName]?Open
var res=oss.ServerURL()+'/';
res+=db.getFilePath().replace(/\\/g,'/');
res+='/0/'+doc.getUniversalID()+'/$File/'+rowData.getName()+'?Open';
return(res);
//Old version
var res=oss.ServerURL()+'/'
res+=db.getFilePath().replace(/\\/g,'/')
res+='/xsp/.ibmmodres/domino/OpenAttachment/'
res+=db.getFilePath().replace(/\\/g,'/')+'/'
res+=doc.getUniversalID()+'/$File/'+rowData.getName()+'?Open'
return(res)
}]]></xp:this.value>
</xp:link>
<xp:eventHandler event="onclick" submit="true"
refreshMode="norefresh" disableValidators="true">
<!-- <xp:this.action><![CDATA[#{javascript:/*
var res=oss.ServerURL()+'/'
res+=database.getFilePath().replace(/\\/g,'/')
res+='/xsp/.ibmmodres/domino/OpenAttachment/'
res+=database.getFilePath().replace(/\\/g,'/')+'/'
res+=doc.getUniversalID()+'/$File/'+rowData.getName()+'?Open'
facesContext.getExternalContext().redirect(res)
//view.postScript("window.open('" + res + "'),'_blank'")
*/}]]></xp:this.action> -->
<xp:this.script><![CDATA[
var linkID = '#{javascript:getClientId("link_test")}';
document.getElementById(linkID).click();]]>
</xp:this.script>
</xp:eventHandler>
</xp:td>
<xp:td styleClass="doc_field_select" id="td3">
<xp:text escape="false" id="cf_del">
<xp:this.value><![CDATA[#{javascript:
return(texticon('minus-5-icon',compositeData.IconSize,compositeData.IconSize,'Delete',false));
}]]>
</xp:this.value>
<xp:this.style><![CDATA[#{javascript:
if(compositeData.IconColor==null)
{
return('');
}
else
{
return('fill:'+compositeData.IconColor+';');
}}]]></xp:this.style>
</xp:text>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" disableValidators="true">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
doc_source.removeAttachment(compositeData.FieldName, rowData.getName());
doc_source.save();
}]]>
</xp:this.script>
</xp:executeScript>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
if (compositeData.postDelete!=null)
{
compositeData.postDelete.getScript().invoke(facesContext, null);
}}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
</xp:td>
</xp:tr>
</xp:table>
</xp:repeat>
<span id="${javascript:compositeData.ID+'_files_progress'}">
</span>
</xp:div>
</xp:view>
And the CSJS script which I use is here:
function files_onchange(urlToUpload, filesInput, filesUpload, filesButton, filesProgress)
{
var urfiles = document.getElementById(filesInput).files;
files_upload(urlToUpload, filesInput, filesUpload, urfiles, 0, filesButton, filesProgress);
}
function files_upload(url, filesInput, uploadID, files, counter, refreshID, filesProgress)
{
//refreshID, uploadID not exact match
console.log(url);
url=""
console.log(url)
var formData = new FormData();
var file = null;
var form = XSP.findForm(filesInput);
//console.log(uploadID);
if (!files) return;
var numberOfFiles = files.length;
file = files[counter];
var max = files.length;
if (counter >= max) return;
formData.append(document.querySelector('[id$=' + uploadID + ']').id, file);
formData.append("$$viewid", dojo.query("input[name='$$viewid']")[0].value);
formData.append("$$xspsubmitid", dojo.query("input[name='$$xspsubmitid']")[0].value);
formData.append("$$xspsubmitvalue", dojo.query("input[name='$$xspsubmitvalue']")[0].value);
formData.append("$$xspsubmitscroll", dojo.query("input[name='$$xspsubmitscroll']")[0].value);
formData.append(form.id, form.id);
var xhr = new XMLHttpRequest();
/* event listners */
xhr.upload.addEventListener("progress", function(e)
{
if (e.lengthComputable)
{
var percentComplete = Math.round(e.loaded * 100 / e.total);
document.getElementById(filesProgress).innerHTML = percentComplete.toString()+'%, ( '+(counter+1).toString()+' / '+numberOfFiles.toString()+' )';
}
else
{
document.getElementById(filesProgress).innerHTML = '...';
}
}, false);
xhr.addEventListener("load", function()
{
counter++;
if (counter >= max)
{
document.getElementById(filesInput).value = "";
if (refreshID)
{
document.querySelector('[id$=' + refreshID + ']').click();
}
}
else
{
files_upload(url, filesInput, uploadID, files, counter, refreshID, filesProgress); // сам себя, ну ебаный ты в рот блять
}
}, false);
xhr.addEventListener("error", function(e)
{
document.getElementById(filesProgress).innerHTML = "Error: "+e;
}, false);
xhr.addEventListener("abort", function()
{
document.getElementById(filesProgress).innerHTML = "Upload cancelled.";
}, false);
xhr.open("POST", url);
xhr.send(formData);
document.querySelector('[id$=' + uploadID + ']').value = '';
}
Probably this is just a Notes feature for storing RichText items? Thanks in advance.

This is indeed the way Lotus Domino stores rich text items or file attachments. Multiple fields of the same name appear in the Properties box of a Notes document.
If your app works without other problems, there is no need to worry.

Related

Getting a 500 Internal Server Error Jquery

While everything is running in the software, I get this error when I make a selection from the dropdown list in only one part. Where am I making a mistake? or is it a server error?
I have not received this error in any Laravel before. When trying to get something from a dropdown list, this error comes to the console and there is no reaction on the site.
https://prnt.sc/vaujzf
<script type="text/javascript">
$("ul#product").siblings('a').attr('aria-expanded','true');
$("ul#product").addClass("show");
$("ul#product #adjustment-create-menu").addClass("active");
var lims_product_array = [];
var product_code = [];
var product_name = [];
var product_qty = [];
$('.selectpicker').selectpicker({
style: 'btn-link',
});
$('#lims_productcodeSearch').on('input', function() {
var warehouse_id = $('#warehouse_id').val();
temp_data = $('#lims_productcodeSearch').val();
if (!warehouse_id) {
$('#lims_productcodeSearch').val(temp_data.substring(0, temp_data.length - 1));
alert('Please select Warehouse!');
}
});
$('select[name="warehouse_id"]').on('change', function() {
var id = $(this).val();
$.get('getproduct/' + id, function(data) {
lims_product_array = [];
product_code = data[0];
product_name = data[1];
product_qty = data[2];
$.each(product_code, function(index) {
lims_product_array.push(product_code[index] + ' (' + product_name[index] + ')');
});
});
});
var lims_productcodeSearch = $('#lims_productcodeSearch');
lims_productcodeSearch.autocomplete({
source: function(request, response) {
var matcher = new RegExp(".?" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(lims_product_array, function(item) {
return matcher.test(item);
}));
},
response: function(event, ui) {
if (ui.content.length == 1) {
var data = ui.content[0].value;
$(this).autocomplete( "close" );
productSearch(data);
};
},
select: function(event, ui) {
var data = ui.item.value;
productSearch(data);
}
});
$("#myTable").on('input', '.qty', function() {
rowindex = $(this).closest('tr').index();
checkQuantity($(this).val(), true);
});
$("table.order-list tbody").on("click", ".ibtnDel", function(event) {
rowindex = $(this).closest('tr').index();
$(this).closest("tr").remove();
calculateTotal();
});
$(window).keydown(function(e) {
if (e.which == 13) {
var $targ = $(e.target);
if (!$targ.is("textarea") && !$targ.is(":button,:submit")) {
var focusNext = false;
$(this).find(":input:visible:not([disabled],[readonly]), a").each(function() {
if (this === e.target) {
focusNext = true;
}
else if (focusNext) {
$(this).focus();
return false;
}
});
return false;
}
}
});
$('#adjustment-form').on('submit', function(e) {
var rownumber = $('table.order-list tbody tr:last').index();
if (rownumber < 0) {
alert("Please insert product to order table!")
e.preventDefault();
}
});
function productSearch(data) {
$.ajax({
type: 'GET',
url: 'lims_product_search',
data: {
data: data
},
success: function(data) {
var flag = 1;
$(".product-code").each(function(i) {
if ($(this).val() == data[1]) {
rowindex = i;
var qty = parseFloat($('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ') .qty').val()) + 1;
$('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ') .qty').val(qty);
checkQuantity(qty);
flag = 0;
}
});
$("input[name='product_code_name']").val('');
if(flag) {
var newRow = $("<tr>");
var cols = '';
cols += '<td>' + data[0] + '</td>';
cols += '<td>' + data[1] + '</td>';
cols += '<td><input type="number" class="form-control qty" name="qty[]" value="1" required step="any" /></td>';
cols += '<td class="action"><select name="action[]" class="form-control act-val"><option value="-">{{trans("file.Subtraction")}}</option><option value="+">{{trans("file.Addition")}}</option></select></td>';
cols += '<td><button type="button" class="ibtnDel btn btn-md btn-danger">{{trans("file.delete")}}</button></td>';
cols += '<input type="hidden" class="product-code" name="product_code[]" value="' + data[1] + '"/>';
cols += '<input type="hidden" class="product-id" name="product_id[]" value="' + data[2] + '"/>';
newRow.append(cols);
$("table.order-list tbody").append(newRow);
rowindex = newRow.index();
calculateTotal();
}
}
});
}
function checkQuantity(qty) {
var row_product_code = $('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ')').find('td:nth-child(2)').text();
var action = $('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ')').find('.act-val').val();
var pos = product_code.indexOf(row_product_code);
if ( (qty > parseFloat(product_qty[pos])) && (action == '-') ) {
alert('Quantity exceeds stock quantity!');
var row_qty = $('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ')').find('.qty').val();
row_qty = row_qty.substring(0, row_qty.length - 1);
$('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ')').find('.qty').val(row_qty);
}
else {
$('table.order-list tbody tr:nth-child(' + (rowindex + 1) + ')').find('.qty').val(qty);
}
calculateTotal();
}
function calculateTotal() {
var total_qty = 0;
$(".qty").each(function() {
if ($(this).val() == '') {
total_qty += 0;
} else {
total_qty += parseFloat($(this).val());
}
});
$("#total-qty").text(total_qty);
$('input[name="total_qty"]').val(total_qty);
$('input[name="item"]').val($('table.order-list tbody tr:last').index() + 1);
}
</script>

For every new ajax call it takes a little more time than the previous call

I am trying to change some data with an ajax call, but the problem is that every new call takes a little more time than the previous one.
So after 10-15 calls, the time from when the ajax request starts and when ajax returns data is like 20 seconds per request.
I also tried to debug, and it seems that the problem is that when I trigger an ajax call, it takes all that time till the controller detects the call, and after controller detects it, it gets executed and returns data immediately.
P.S. When i comment out these 2 intervals, it works perfectly. So i guess these intervals are blocking this request form happening immediately.
Also can it be a problem with Google Chrome? Because i guess in Microsoft Edge works perfectly (as far i made a test 2 times).
html:
<div class="table-responsive">
<table class="table table-condensed table-hover usersTable">
<thead>
<tr>
<th style="width: 20%">Benutzer</th>
<th></th>
<th></th>
#foreach (var item in Model.Skills)
{
<th title="#item.Name">#item.ShortName</th>
}
<th class="text-center">Extension</th>
<th class="text-center">Total Calls</th>
<th class="text-center">Calls per hour</th>
<th class="text-center">Average Call Duration</th>
</tr>
</thead>
<tbody class="usersTableBody"></tbody>
</table>
<div class="col-md-12 text-center noSignedInUser" style="display: none;">
<h4 style="color: lightgrey">There is no signed in user</h4>
</div>
js:
$(function () {
$('.usersTableBody').on('click', '.hasSkill', function () {
var userId = $(this).parent().data('id');
var skillId = $(this).data('id');
if ($(this).hasClass('skillIsActive')) {
addRemoveSkill(userId, skillId, false, $(this))
}
else {
addRemoveSkill(userId, skillId, true, $(this))
}
});
//add or remove a skill to a user with ajax
function addRemoveSkill(userId, skillId, add, element) {
$.ajax({
url: '#Url.Action("AddRemoveSkill","Home")',
data: { userId: userId, skillId: skillId, add: add },
success: function (data) {
if(data == true) {
if (add == false)
{
$(element).addClass('skillIsInactive')
$(element).removeClass('skillIsActive')
}
else {
$(element).addClass('skillIsActive')
$(element).removeClass('skillIsInactive')
}
$(element).addClass('recentlyUpdated');
hasAllSkillsDisabled($(element));
}
}
});
}
function hasAllSkillsDisabled(element) {
parent = $(element).parent();
var hasAllDisabled = true;
$.each(parent.children('td'), function (i, item) {
if ($(item).hasClass('skillIsActive'))
{
hasAllDisabled = false;
}
});
if (hasAllDisabled == true)
{
$(parent).addClass('hasAllSkillsDisabled');
}
else {
$(parent).removeClass('hasAllSkillsDisabled');
}
}
})
two other functions that gets data every 1000ms
getUserDatas();
getSkillHeader();
var detectClass = 0;
function getUserDatas() {
var type = $('#Type').val();
var skill = $('#Skill').val();
$.ajax({
url: '#Url.Action("GetUsersDataWithAjax", "Home")',
data: { type: type, skill: skill },
success: function (data) {
if (data.length == 0) {
$('.noSignedInUser').show();
}
else {
$('.noSignedInUser').hide();
}
if (data != false) {
$.each(data, function (i, item) {
var tr = $('tr[data-id="' + item.Id + '"].agentTr');
//if that row already exists or its new
if (!tr.length)
{
//if new create html and append to table body
var dontHaveSkills = "dontHaveSkills";
if (item.hasSkills) {
dontHaveSkills = "";
}
var hasAllSkillsDisabled = "";
if (item.hasSkills && item.HasAllSkillsDisabled) {
hasAllSkillsDisabled = "hasAllSkillsDisabled";
}
var html = '';
html += '<tr data-id="' + item.Id + '" class="agentTr ' + dontHaveSkills + ' ' + hasAllSkillsDisabled + ' time' + detectClass + '">';
html += '<td>' + item.Name + '</td>';
html += '<td class="stateName"><div class="text-right ' + item.State.NameClass + '">' + item.State.Name + '</div></td>';
html += '<td class="stateCircle"><div class="statusCircle ' + item.State.CircleClass + '"</div></td>';
$.each(item.Skills, function (j, skill) {
var klasa = "";
if (skill.IsActive == true) {
klasa = "hasSkill skillIsActive";
}
else if (skill.IsActive == false) {
klasa = "hasSkill skillIsInactive";
}
else {
klasa = "unableSkill";
}
html += '<td data-id="' + skill.Id + '" class="' + klasa + '" title="' + skill.Name + '">' + skill.ShortName + '</td>';
if (j == 25) {
return false;
}
});
html += '<td class="text-center extension">' + item.Extension + '</td>';
html += '<td class="text-center totalCalls">' + item.AvgCalls.TotalCalls + '</td>';
html += '<td class="text-center callsPerHour">' + item.AvgCalls.CallsPerHour + '</td>';
html += '<td class="text-center avgCallDuration">' + item.AvgCalls.AvgCallDuration + '</td>';
html += '</tr>';
$('.usersTableBody').append(html);
}
else {
//else if its existing update datas
tr.removeClass('dontHaveSkills hasAllSkillsDisabled');
var detect = 'time' + (detectClass - 1);
tr.removeClass(detect);
if (!item.hasSkills) {
tr.addClass('dontHaveSkills');
}
if (item.hasSkills && item.HasAllSkillsDisabled) {
tr.addClass('hasAllSkillsDisabled');
}
var stateName = tr.children('.stateName');
stateName.children('div').text(item.State.Name);
stateName.children('div').removeClass('bereitName besetzName nbzName pauseName abgemeldetName');
stateName.children('div').addClass(item.State.NameClass);
var stateCircle = tr.children('.stateCircle');
stateCircle.children('div').removeClass('Online OnCall AfterTime Pause LoggedOff');
stateCircle.children('div').addClass(item.State.CircleClass);
$.each(item.Skills, function (j, skill) {
var skillElement = tr.children('td[data-id="' + skill.Id + '"]');
if (!skillElement.hasClass('recentlyUpdated')) {
skillElement.removeClass('hasSkill skillIsActive skillIsInactive unableSkill');
if (skill.IsActive == true) {
skillElement.addClass('hasSkill skillIsActive');
}
else if (skill.IsActive == false) {
skillElement.addClass('hasSkill skillIsInactive');
}
else {
skillElement.addClass('unableSkill');
}
}
else {
skillElement.removeClass('recentlyUpdated');
}
if (j == 25) {
return false;
}
});
var extension = tr.children('.extension');
var totalCalls = tr.children('.totalCalls');
var callsPerHour = tr.children('.callsPerHour');
var avgCallDuration = tr.children('.avgCallDuration');
extension.text(item.Extension);
totalCalls.text(item.AvgCalls.TotalCalls);
callsPerHour.text(item.AvgCalls.CallsPerHour);
avgCallDuration.text(item.AvgCalls.AvgCallDuration);
tr.addClass('time' + detectClass);
}
var allTr = $('tr.agentTr');
});
}
$('tr.agentTr').each(function (i, item) {
if (!$(item).hasClass('time' + detectClass)) {
item.remove();
}
});
detectClass++;
$('.usersTable').waitMe('hide');
}
});
}
function getSkillHeader() {
$.ajax({
url: '#Url.Action("GetSkillHeaderWithAjax", "Home")',
success: function (data) {
if (data.length == 0) {
$('.allSkillsHidden').show();
}
else {
$('.allSkillsHidden').hide();
}
if (data != false) {
$.each(data, function (i, item) {
var tr = $('tr[data-id="' + item.Id + '"].skillTr');
if (!tr.length) {
var html = '';
html += '<tr data-id="' + item.Id + '" class="skillTr">';
html += '<th class="name">' + item.Name + '</th>';
html += '<th class="text-center waitingQueue">~</th>';
html += '<th class="text-center activeCalls">~</th>';
html += '<th class="text-center totalFreeAgents">' + item.TotalFreeAgents + '</th>';
html += '<th class="text-center totalSignedInAgents">' + item.TotalSignedInAgents + '</th>';
html += '</tr>';
$('.skillsHeaderTableBody').append(html);
}
else {
var name = tr.children('.name');
name.text(item.Name);
var totalFreeAgents = tr.children('.totalFreeAgents');
totalFreeAgents.text(item.TotalFreeAgents);
var totalSignedInAgents = tr.children('.totalSignedInAgents');
totalSignedInAgents.text(item.TotalSignedInAgents);
}
});
}
$('.skillHeaderTable').waitMe('hide');
}
});
}
//call getUserDatas method every 1 seconds
setInterval(function () {
getUserDatas();
},1000);
setInterval(function () {
getSkillHeader();
}, 1000);
C#:
public ActionResult AddRemoveSkill(string userId, string skillId, bool add)
{
try
{
var skill = _sysCfgContext.GetUserSkill(Guid.Parse(userId), Guid.Parse(skillId));
if (add)
skill.IsActive = true;
else
skill.IsActive = false;
_sysCfgContext.EditUserSkill(skill);
_sysCfgContext.SaveChanges();
return Json(true, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
I'm using the assumption that those two functions aren't dependent upon one another.
function getUserDatas() {
var type = $('#Type').val();
var skill = $('#Skill').val();
return $.ajax(function() {
//Code omitted for brevity
});
}
function getSkillHeader() {
return $.ajax(function() {
//Code omitted for brevity
});
}
getUserDatas();
getSkillHeader();
var interval = setInterval(function(){
$.when(getUserDatas(), getSkillHeader())
.then(function(resultUserDatas,resultSkillHeader)
},1000);
I have to add that this is the untested code.

Disable button on ajax submit

I have the following JS and HTML code and I want to disable the button when ajax request is submitting so the user wont be able to double click and disturb the process.
function doReshare(_intPostId) {
if(typeof cLogin === 'undefined')
var cLogin = checkLogin();
if(cLogin!=true)
return;
var date = new Date();
var mainId = _intPostId;
var type = 1;
var active = 0;
var postFinded = 0;
jQuery(".reshare_" + _intPostId).each(function() {
postFinded = 1;
objElement = jQuery(this);
if(objElement.hasClass('sm2_playing') || objElement.hasClass('sm2_paused')) {
// track is active
active = 1;
}
if(objElement.hasClass('is_album')) {
mainId = objElement.closest('div.playlist-box').attr('id').replace('album_', '');
// mainId = objElement.data('mainid');
}
var intLikesCurrentCount = parseInt(objElement.find(".likes_count").first().text(), 10);
if(!objElement.find(".refeed_fct").hasClass("active")) {
if(active)
jQuery('.player-icons.dorepost').addClass('active');
objElement.find(".refeed_fct").addClass("active");
//objElement.find(".likes_count").html("<i class=\"fa fa-heart-o\"></i> " + (intLikesCurrentCount + 1));
} else {
objElement.find(".refeed_fct").removeClass("active");
if(active)
jQuery('.player-icons.dorepost').removeClass('active');
type = 0;
//objElement.find(".likes_count").html("<i class=\"fa fa-heart-o\"></i> " + (intLikesCurrentCount - 1));
}
});
if(!postFinded) {
if(!jQuery(".player-icons.dorepost").hasClass("active")) {
jQuery('.player-icons.dorepost').addClass('active');
} else {
jQuery('.player-icons.dorepost').removeClass('active');
}
}
jQuery("#vowave").append('<img width="1" height="1" src="/reshare/' + mainId + '/' + type + '?time=' + date.getTime() + '" />');
}
and the html
<span class="refeed_fct" onclick="doReshare(10309)">
<i class="fa fa-retweet"></i> <div class="inline hidden-mobile">Repost</div>
</span>
Thank you
Maybe you should set the objElement's onclick listener to an empty function

Enter key not working in Firefox - onkeypress (I know there are "answers" but...)

I've seen all the posts about this issue but I still can't get the enter key to work in Firefox. Here are all my iterations of code and I've obviously changed it a hundred times to try and make it work. I can get it to work in IE, not Firefox. Alternate question: I'm new to xPages. Where do I define a function in an xPage or do I have to make a script library and add it to resources? Thanks all.
Mike
var metaChar = false;
var key = event.keyCode || event.which;
if (key == 13) {
metaChar = true;
event.returnValue = true;
alert("true13");
}
if (key != 13) {
if (metaChar) {
alert("false");
metaChar = false;
} else {
alert("true");
event.returnValue = false;
}
}
 
 
/*
var vevent = event.keyCode || event.key // IE does not pass event to the function
if(vevent == window.event){
code = event.keyCode;
}else{
code = event.key;
}
if(code == 13){
event.returnValue = true;
alert("True");
} else {
event.returnValue = false;
return false;
alert("False");
}
*/
var e = event.keyCode || event.which;
charCode = e.keyCode || e.which;
if(charCode == 13){
return true;
alert("True");
} else {
return false;
alert("False");
}
I suspect your issue lies in trying to use event in your javascript. In XPages you need to use a different reference thisEvent, some info at this link under "Getting event information". This is a quirk of the way XPages adds events on page load.
For your situation, I created a simple example XPage, which shows you how to capture the enter key in an eventHandler or using an inline function if you want to go that route. This works for me in Chrome, Firefox and Internet Explorer 11.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel id="panel1">
<script type="text/javascript">
var enterKey = function(eventParam) {
var key = eventParam.keyCode || eventParam.which;
console.log("key = " + key);
if (key == 13) {
alert("script function - enter");
return true;
}else{
alert("script function - other character");
return false;
}
}
</script>
<xp:inputText id="button1">
<xp:eventHandler event="onkeypress" submit="false">
<xp:this.script><![CDATA[
var key = thisEvent.keyCode || thisEvent.which;
console.log("key = " + key);
if (key == 13) {
alert("button event script - enter");
return true;
}else {
alert("button event script - other character");
return false;
}
]]>
</xp:this.script>
</xp:eventHandler>
</xp:inputText>
<xp:br />
<xp:br />
<xp:inputText id="button2">
<xp:eventHandler event="onkeypress" submit="false">
<xp:this.script><![CDATA[
enterKey(thisEvent);
]]>
</xp:this.script>
</xp:eventHandler>
</xp:inputText>
</xp:panel>
</xp:view>

AJAX response doesn't run any script

My page gets a response from response_ajax.php with this code:
<input class="btn" name="send_button" type="button" value="check"
onClick=
"xmlhttpPost('/response_ajax.php',
'MyForm',
'MyResult',
'<img src=/busy.gif>')";
return false;"
>
I get a response; however, jQuery scripts don't work with an arrived code. I'm trying to add script inside response_ajax.php, but nothing happens:
<?php
// ... //
echo '
<div id="whois-response">
<pre>' .$str. '</pre>
</div>
<script>
(function($){
$(function(){
alert("loaded");
});
})(jQuery);
</script>
';
?>
xmlhttpPost function:
function xmlhttpPost(strURL,formname,responsediv,responsemsg) {
var xmlHttpReq = false;
var self = this;
// Xhr per Mozilla/Safari/Ie7
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// per tutte le altre versioni di IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
// Quando pronta, visualizzo la risposta del form
updatepage(self.xmlHttpReq.responseText,responsediv);
}
else{
// In attesa della risposta del form visualizzo il msg di attesa
updatepage(responsemsg,responsediv);
}
}
self.xmlHttpReq.send(getquerystring(formname));
}
function getquerystring(formname) {
var form = document.forms[formname];
var qstr = "";
function GetElemValue(name, value) {
qstr += (qstr.length > 0 ? "&" : "")
+ escape(name).replace(/\+/g, "%2B") + "="
+ escape(value ? value : "").replace(/\+/g, "%2B");
//+ escape(value ? value : "").replace(/\n/g, "%0D");
}
var elemArray = form.elements;
for (var i = 0; i < elemArray.length; i++) {
var element = elemArray[i];
var elemType = element.type.toUpperCase();
var elemName = element.name;
if (elemName) {
if (elemType == "TEXT"
|| elemType == "TEXTAREA"
|| elemType == "PASSWORD"
|| elemType == "BUTTON"
|| elemType == "RESET"
|| elemType == "SUBMIT"
|| elemType == "FILE"
|| elemType == "IMAGE"
|| elemType == "HIDDEN")
GetElemValue(elemName, element.value);
else if (elemType == "CHECKBOX" && element.checked)
GetElemValue(elemName,
element.value ? element.value : "On");
else if (elemType == "RADIO" && element.checked)
GetElemValue(elemName, element.value);
else if (elemType.indexOf("SELECT") != -1)
for (var j = 0; j < element.options.length; j++) {
var option = element.options[j];
if (option.selected)
GetElemValue(elemName,
option.value ? option.value : option.text);
}
}
}
return qstr;
}
function updatepage(str,responsediv){
document.getElementById(responsediv).innerHTML = str;
}
I may be wrong, but I'm pretty sure you can't do multiline strings unless it is configured to do so (and running a newer version of PHP):
echo '
<div id="whois-response">
<pre>' .$str. '</pre>
</div>
<script>
(function($){
$(function(){
alert("loaded");
});
})(jQuery);
</script>
';
Try changing that to:
echo <<<EOD
<div id="whois-response">
<pre> $str </pre>
</div>
<script>
(function($){
$(function(){
alert("loaded");
});
})(jQuery);
</script>
EOD;
I think your AJAX response is a PHP error instead of the script you think it is returning.
Got it to work by adding jQuery staff as a function
function updatepage(str,responsediv){
document.getElementById(responsediv).innerHTML = str;
(function($){
$(function(){
$('html').my_jQuery_staff();
});
})(jQuery);
}
Main JavaScript file with jQuery:
// ~~ jQuery ~~
$(document).ready(function () {
$.fn.my_jQuery_staff= function() {
return this.each(function() {
// Include jQuery staff here.
});
};
$('html').my_jQuery_staff();
});

Resources