$(":mobile-pagecontainer" ).pagecontainer( "change" not working on second time - jquery-mobile

On click of a button , i am reloading the same page this way
(document).on('click', '.cancelyes', function(event) {
alert('herree');
var uuid = '123';
var screen_id = '910';
var cust_id = '122';
var minimum_order = 133;
var addreslabel = '222'
$(":mobile-pagecontainer" ).pagecontainer( "change", "index.html?UUID=" + uuid + '&screen_id=' + screen_id + '&cust_id=' + cust_id + '&minimum_order=' + minimum_order + '&addreslabel=' + addreslabel+ '&accessedfrom=' + accessedfrom );
});
This works fine for the first time , but if i re do the operation , why doesn't its loading the same page again ??

From Pagecontainer documentation on options:
allowSamePageTransition (default: false)
By default, change() ignores requests to change to the current active page. Setting this option to true allows the request to execute.

Related

Create jQuery ui dialog box for each row in a table

I am trying to append rows to a table using an array called searchResults. Everything works as expected until I introduce the jQuery UI dialog box. The problem is I need a new dialog box for each row in the first column. I'm pretty new to all of this so I'm pretty sure I'm using the index incorrectly at times. This is just to give you an idea of what I'm trying to accomplish. Any ideas how to do this correctly?
for (var i = 0; i < searchResults.length; i++)
{
$('#patientFileDialog[i]').dialog();
$'#openPFDialog[i]').click(function() {
$('#patientFileDialog[i]').dialog('open');
});
var dialog[i] = $(`<div id="patientFileDialog[i]" title="Patient File">${searchResults[i].patientWebLink}</div>`);
body.append('<tr>'+
`<td><button id="openPFDialog[i]">Click Here</button></td>` +
`<td>${searchResults[i].patientFirstName}</td>` +
`<td>${searchResults[i].patientLastName}</td>` +
`<td>${searchResults[i].patientDateOfBirth}</td>` +
`<td>${searchResults[i].patientDataPulseID}</td>` +
`<td>${searchResults[i].patientLaserFicheID}</td>` +
'</tr>')
}
After looking at your code a bit more I think I can see what you are trying to do. Working JSFiddle, with some faked searchResults so we can see it in action.
There are a few problems with the code in your question:
Using selectors like $('#patientFileDialog[i]') and $'#openPFDialog[i]') will try to match elements on the page with those IDs. AFAICT those don't actually exist yet, you are trying to create them.
var dialog[i] = ... sets up some divs as strings, but those are never added to the page;
As I mentioned in my comment, there are some syntax errors, maybe just typos and mixed up formatting here on SO;
Here's an updated version of the code. Notable changes:
Instead of adding an event handler for every individual openPFDialog button, it is better practice to add just one which matches them all. That single handler can then work out which button was clicked, and take the right action for just that one, not all of them. In this case if you have all your buttons use IDs that match openPFDialog-X, where X is a number, you can target anything matching that pattern (using a starts with selector, and find the X by removing the openPFDialog- part with replace.
There's an added complication with the above though. Selectors parsed at page load will only match elements that exist at that time. In this case, you're adding new elements to the page, and a selector defined at page load won't match them. The solution is to select instead some parent element which does exist at page load, and filter. This is called event delegation (search for the paragraph starting with "Delegated event handlers").
Working from what you have, I am guessing the patientFileDialogs you create should be placed inside some parent element which is not displayed on the page? That's what I've done.
Here's the code (and working JSFiddle):
var dialog, i;
// Single click handler for anything that starts with "openPFDialog-".
// Since those elements don't exist on the page yet, we need to instead
// select a parent object, say the body, and filter for clicks on our
// elements starting with our pattern
$('body').on('click', '[id^=openPFDialog]', function() {
// We need to find the "i"
i = $(this).attr('id').replace(/openPFDialog-/,'');
console.log('clicked on id', i);
$('#patientFileDialog-' + i).dialog();
});
for (var i = 0; i < searchResults.length; i++) {
// Create a new div with ID like "patientFileDialog-1", using the current
// search result
dialog = $('<div id="patientFileDialog-' + i + '" title="Patient File">' + searchResults[i].patientWebLink + '</div>');
// Add it to the page. I've use a div with ID dialogs which is hidden
$('#dialogs').append(dialog);
$('table').append('<tr>'+
'<td><button id="openPFDialog-' + i + '">Click Here</button></td>' +
'<td>' + searchResults[i].patientFirstName + '</td>' +
'<td>' + searchResults[i].patientLastName + '</td>' +
'<td>' + searchResults[i].patientDateOfBirth + '</td>' +
'<td>' + searchResults[i].patientDataPulseID + '</td>' +
'<td>' + searchResults[i].patientLaserFicheID + '</td>' +
'</tr>');
}
Update
One last suggestion - manipulating the DOM by adding/removing elements is slow. If you need to do that for each element in an array, it is best to avoid actually adding your content on each iteration, and rather just build up a string. Then once you're done iterating, just add the big single string, so you're chaning the DOM just once. Here's the basic changes needed to do that:
// Add some new variables to hold our big strings
var dialog, dialogs, row, rows, i;
// ... your code ...
for (var i = 0; i < searchResults.length; i++) {
// Create the dialog ...
dialog = ...
// Append it to our big string of all dialogs
dialogs += dialog;
// Same approach for rows
row = '<tr>'+ ... all that stuff
rows += row;
}
// Finished iterating, nothing added to DOM yet. Do it all at once::
$('#dialogs').append(dialogs);
$('table').append(rows);
Here is what I finally ended up having to do:
$(document).ready(function(){
if ($('[attr="searchResultsJson"]').length)
{
$('.approval-outer-wrap').prepend(drawTable());
$('.approval-outer-wrap').append('<div id="result-details" title="Search Result Detail"><p></p></div>')
}
$('body').on('click', '[id^=openPFDialog]', function() {
var result = $(this).parents('tr').data('result');
$('#result-details p').html(result.patientFirstName);
$('#result-details').dialog();
});
});
function drawTable(){
var table = $('<table id="search-results" />');
var header = $('<thead />');
table.append(header);
header.append('<tr><th>Patient File</th><th>First Name</th><th>Last Name</th><th>Date of Birth</th><th>Data Pulse ID</th><th>Laserfiche ID</th></tr>');
var body = $('<tbody />');
table.append(body);
var json = $('[attr="searchResultsJson"] [type="text"]').text();
var searchResults = JSON.parse(json);
for (var i = 0; i < searchResults.length; i++) {
body.append(`<tr data-result='${JSON.stringify(searchResults[i])}'>`+
`<td><button id="openPFDialog-` + i + `">🔍</button></td>` +
`<td>${searchResults[i].patientFirstName}</td>` +
`<td>${searchResults[i].patientLastName}</td>` +
`<td>${searchResults[i].patientDateOfBirth}</td>` +
`<td>${searchResults[i].patientDataPulseID}</td>` +
`<td>${searchResults[i].patientLaserFicheID}</td>` +
'</tr>');
}
return table;
}
Consider the following code.
function showPatientDialog(cnt){
$("#patient-file-dialog").html(cnt).dialog("open");
}
var d = $("<div>", {
id: "patient-file-dialog",
title: "Patient File"
})
.appendTo("body")
.dialog({
autoOpen: false
});
$.each(searchResults, function(i, result) {
var row = $("<tr>").appendTo(body);
$("<td>").appendTo(row).html($("<button>", {
id: "open-pdf-dialog-" + i
}).click(function() {
showPatientDialog(result.patientWebLink);
}));
$("<td>").appendTo(row).html(result.patientFirstName);
$("<td>").appendTo(row).html(result.patientLastName);
$("<td>").appendTo(row).html(result.patientDateOfBirth);
$("<td>").appendTo(row).html(result.patientDataPulseID);
$("<td>").appendTo(row).html(result.patientLaserFicheID);
});

Why Document DB procedure returns only 100 docs on querydocument?

I have below procedure in Document DB. It executes fine from DocumentDb script explorer but the result it returns is partial. I have more than 250 documents satisfying its given where clause which I checked in query explorer. But when I run procedure from script explorer count(defined in procedure) is always 100.
Below is my procedure -
function getInvoice(pageNo, numberOfRecords, member, searchText, customerGroupId,ResellerId) {
var collectionReseller = getContext().getCollection();
var filterquery ;
var count=0, invoiceAmountTotal=0, referalCommissionTotal=0, developerCommissionTotal=0;
var customerIdString='';
var InvoiceList = [];
var whereClause;
if (customerGroupId != "") {
filterquery = 'SELECT c.id from c where c.Type="Customer" and c.CustomerGroupID="' + customerGroupId + '"';
var isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery,
function (err, documents, responseOptions) {
var docCount = documents.length;
documents.forEach(function (doc) {
docCount--;
if (docCount > 0)
customerIdString = customerIdString + '"' + doc.id + '", '
else
customerIdString = customerIdString + '"' + doc.id + '" '
})
whereClause = 'where r.Type="Invoice" and r.CustomerID IN (' + customerIdString + ')'
var filterquery1 = 'SELECT * FROM root r ';
if (member.length > 0) {
member.forEach(function (val, i) {
whereClause = whereClause + ' and contains(r.' + member[i] + ',"' + searchText[i] + '")';
});
}
isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery1 + whereClause,
function (err, invoiceDoc) {
var qr = filterquery1 + whereClause;
count = invoiceDoc.length;
invoiceDoc.forEach(function (doc) {
invoiceAmountTotal = parseFloat(invoiceAmountTotal) + parseFloat(doc.InvoiceAmount);
referalCommissionTotal = parseFloat(referalCommissionTotal) + parseFloat(doc.ReferralCommission);
developerCommissionTotal= parseFloat(developerCommissionTotal) + parseFloat(doc.DeveloperCommission);
InvoiceList.push(doc);
});
InvoiceList.sort(SortByID);
InvoiceList = InvoiceList.slice(pageNo * numberOfRecords, pageNo * numberOfRecords + numberOfRecords);
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
getContext().getResponse().setBody(JSON.stringify({ InvoiceList, count, invoiceAmountTotal, referalCommissionTotal, developerCommissionTotal }));
});
});
}
else
{
whereClause = ' where r.Type = "Invoice" and r.ResellerID = "'+ ResellerId + '"';
filterquery = 'SELECT * FROM root r ';
if(member.length > 0) {
member.forEach(function (val, i) {
whereClause = whereClause + ' and contains(r.' + member[i] + ',"' + searchText[i] + '")';
});
}
filterquery = filterquery + whereClause;
var isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery,
function (err, documents, responseOptions) {
if (err) throw err;
invoiceDoc = documents;
count =invoiceDoc.length;
invoiceDoc.forEach(function (doc) {
InvoiceList.push(doc);
invoiceAmountTotal = parseFloat(invoiceAmountTotal) + parseFloat(doc.InvoiceAmount);
referalCommissionTotal = parseFloat(referalCommissionTotal) + parseFloat(doc.ReferralCommission);
developerCommissionTotal= parseFloat(developerCommissionTotal) + parseFloat(doc.DeveloperCommission);
});
InvoiceList.sort(SortByID);
InvoiceList = InvoiceList.slice(pageNo * numberOfRecords, pageNo * numberOfRecords + numberOfRecords);
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
getContext().getResponse().setBody(JSON.stringify({ InvoiceList, count, invoiceAmountTotal, referalCommissionTotal, developerCommissionTotal }));
});
}
function SortByID(a, b) {
var aName = a.UpdatedOn.toLowerCase();
var bName = b.UpdatedOn.toLowerCase();
return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Any help will be highly appreciated..
If you want to get all 250 back in one shot, you need to populate the options parameter for queryDocuments() with a pageSize field. It's an optional third parameter for that function call. Without it, this server-side API will default to 100.
You can also set pageSize to -1 to get you all documents. However, for server-side stored procedures, I recommend against this. Rather, you need to handle paging using the continuation token. If you want it to be really robust you also need to deal with premature shutdown of the stored procedure.

SAPUI5 SplitApp Master and Detail Page not working

I am trying to create a Detail-Master page using OData service in SAPUI5. Everything works fine in the Master page.
When I clicked on the item on the Master page, it brings down to the Detail page, but I could not get the data in the Detail page.
I have put the alert function to debug in the Detail page. This code will never be executed.
var oList = new sap.m.List({headerText: "Material Details", items:
[
new sap.m.DisplayListItem({label:"Material:",value:"{Material}"}),
new sap.m.DisplayListItem({label:"Material:",value:{
path:"Materials",
formatter:function(iValue){
alert('Here!!');
var test = this.getBindingContext();
console.log('SS:' + test);
var currentdate = new Date();
var datetime = "Last Sync: " + currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear() + " # "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds();
return currentdate + " sq km";
}
}})
]});
Any idea why? do we need to get the model ?
Herer is the full source code:
https://github.com/ferrygun/SAPUI5

Trigger cocoon add_association from javascript

I am using cocoon and I want to automatically add a child record when a date(can be multiple dates) in a date picker is selected.
I can trap the date selections in coffeescript like this, but I don't know how to get a child record added through cocoon i.e. by emulating what happens when the link_to_add_association is fired.
$(".form_multidate").datepicker().on 'changeDate', (e) -> alert(e.dates)
the cocoon setup is a standard nested form, no tricks, working fine on the page.
EDIT: Code mentioned in comment re binding calendar:
$(document).ready(function() {
$('#other_request_details')
.bind('cocoon:after-insert', function() {
return $('.datepicker-single').datepicker({
dateFormat: "DD, dd M yy"
});
});
});
Calling a JS function in order to add a new record with Cocoon is not possible. The only thing you can do is trigger the click event of the add association button.
If you see Cocoon's library code you will see that all new record functionality is bound to the click button
$(document).on('click', '.add_fields', function(e) {
e.preventDefault();
var $this = $(this),
assoc = $this.data('association'),
assocs = $this.data('associations'),
content = $this.data('association-insertion-template'),
insertionMethod = $this.data('association-insertion-method') || $this.data('association-insertion-position') || 'before',
insertionNode = $this.data('association-insertion-node'),
insertionTraversal = $this.data('association-insertion-traversal'),
count = parseInt($this.data('count'), 10),
regexp_braced = new RegExp('\\[new_' + assoc + '\\](.*?\\s)', 'g'),
regexp_underscord = new RegExp('_new_' + assoc + '_(\\w*)', 'g'),
new_id = create_new_id(),
new_content = content.replace(regexp_braced, newcontent_braced(new_id)),
new_contents = [];
if (new_content == content) {
regexp_braced = new RegExp('\\[new_' + assocs + '\\](.*?\\s)', 'g');
regexp_underscord = new RegExp('_new_' + assocs + '_(\\w*)', 'g');
new_content = content.replace(regexp_braced, newcontent_braced(new_id));
}
new_content = new_content.replace(regexp_underscord, newcontent_underscord(new_id));
new_contents = [new_content];
count = (isNaN(count) ? 1 : Math.max(count, 1));
count -= 1;
while (count) {
new_id = create_new_id();
new_content = content.replace(regexp_braced, newcontent_braced(new_id));
new_content = new_content.replace(regexp_underscord, newcontent_underscord(new_id));
new_contents.push(new_content);
count -= 1;
}
var insertionNodeElem = getInsertionNodeElem(insertionNode, insertionTraversal, $this)
if( !insertionNodeElem || (insertionNodeElem.length == 0) ){
console.warn("Couldn't find the element to insert the template. Make sure your `data-association-insertion-*` on `link_to_add_association` is correct.")
}
$.each(new_contents, function(i, node) {
var contentNode = $(node);
insertionNodeElem.trigger('cocoon:before-insert', [contentNode]);
// allow any of the jquery dom manipulation methods (after, before, append, prepend, etc)
// to be called on the node. allows the insertion node to be the parent of the inserted
// code and doesn't force it to be a sibling like after/before does. default: 'before'
var addedContent = insertionNodeElem[insertionMethod](contentNode);
insertionNodeElem.trigger('cocoon:after-insert', [contentNode]);
});
});

JQUERY call to Controller Action: String Parameter truncated if containing 'space' character

I have a view that accepts 2 string parameters and 2 date values. User hits search button and they get filtered output to the screen. This all works perfectly well until a user inputs a string with a space. i.e. they can search for 'waste' but not 'waste oil'.
Interestingly, in the latter, the parameter is ok from Javascript before the call is made. But on entering the controller code it goes form being 'waste oil' on client to 'waste'. When this happens the other parameters get set to NULL crashing the system.
I've tried replacing the spaces if present with '#' character then stripping out and putting back in ' ' on the controller side. This is a messy fudge and only appears to work with one parameter.
There must be a simple explanation for this parameter data loss, any comments much appreciated
Not sure a code example is needed but here it is anyway if it help:
My controller header :
public ActionResult IndexSearch(int? page, string searchText,string searchTextSite,string StartDate,string EndDate)
{
My HTML Javascript :
function Search(sSearchText,sSite) {
sSearchText = sSearchText.toString().replace(" ", "#");
sSite = sSite.toString().replace(" ", "#");
debugger;
alert($("#AbsolutePath").val() + "Waste.mvc/IndexSearch?searchText=" + sSearchText + "&searchTextSite=" + sSite + "&StartDate=" + $('#StartDate').val() + "&EndDate=" + $('#EndDate').val());
$("#ResultsList").load($("#AbsolutePath").val() + "Waste.mvc/IndexSearch?searchText=" + sSearchText + "&searchTextSite=" + sSite + "&StartDate=" + $('#StartDate').val() + "&EndDate=" + $('#EndDate').val(),
function() {
$('#LoadingGif').empty();
});
$('#LoadingGif').empty().html('<img src="' + $("#AbsolutePath").val() + 'Content/images/ajax-loader.gif" alt="Loading image" />');
}
You are not URL encoding your parameters when sending the AJAX request because you are using string concatenations when building the url. You could use the following technique in order to have properly encoded values:
var url = $('#AbsolutePath').val() + 'Waste.mvc/IndexSearch';
var data = {
searchText: sSearchText,
searchTextSite: sSite ,
StartDate: $('#StartDate').val(),
EndDate: $('#EndDate').val()
};
$('#ResultsList').load(url, data, function() {
$('#LoadingGif').empty();
});
Now you will get correct values on the server.

Resources