I inherited this project and am trying to correct a few bugs. This particular issue deals with the user double clicking a box in a form(built in conveyor_maint.php), then picking a value in a window that pops up (getPartNumber.php) and then having that value pass back down the form. It successfully pushes the value into the clipboard, but I cannot figure out how to get the value to go back to the form. I would like it to update the form each time the user picks a value in the popup window, but could have it only update upon closure of the popup window too.
Here are the details:
The table is in conveyor_maint.php
<th> Override Head Tail </th>
<td><input type="text" name="cd_headtail_ovrd" value="$cd_headtail_ovrd" size="20"
ondblclick="getPartNumber('cd_headtail_ovrd','desc_htail_ovrd','TAIL');"
title="DOUBLE CLICK to display a list of tails you may select from. This will override the calculated head tail when choosing BOM data. YOu may leave this field blank.">
<input type="display" name="desc_htail_ovrd"
value="$desc_htail_ovrd" size="30" readonly></td></tr>
When the block is double clicked, it runs the javascript function getpartNumber, from the included file javascript.php
<script language="javascript">
function getPartNumber(field1, field2, filter) {
var user = '$user_login'
var url = 'getPartNumber.php?user_login=' + user + '&filter=' + filter + '&field1=' + field1 + '&field2=' + field2
window.open(url,'Get_Part_Number','height=700,width=900,scrollbars=yes')
getClipboardContents(field1, field2);
}
async function getClipboardContents(field1, field2) {
try {
const text = await navigator.clipboard.readText();
console.log('Pasted content: ', text);
var partarray = text.split("!")
var partno = partarray[0]
var partdesc = partarray[1]
if (text != "") {
window.document.forms[0].elements[field1].value = partno
window.document.forms[0].elements[field2].value = partdesc
}
} catch (err) {
console.error('Failed to read clipboard contents: ', err);
}
}
</script>
The javascript launches the window.open command to open the pop-up GetPartNumber.php
GetPartNumber.php builds a table which the user selects the value to be pushed back to the original form.
It relies on a state_change to push the value into the clipboard:
function state_Change() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status==200) {
myhtml = xmlhttp.responseText;
var dataarray = myhtml.split("~");
var retdata = dataarray[1];
navigator.clipboard.writeText(retdata);
} else {
alert("Problem retrieving XML data:" + xmlhttp.statusText)
}
}
}
This works, as I click the different choices in the popup, they can be pasted into a text file correctly.
Now, this used to work with the following code, but upgrades to the server and related software broke it.
Each time a choice is made in the pop-up, it runs SelectPart()
function SelectPart(partno, user_login) {
window.document.curform.partno.value = partno;
var url = 'getPartData.php?partno=' + partno + '&user_login=' + user_login;
loadXMLDoc(url)
}
Subsequently, getPartData.php runs and echoes the same data I pushed to the clipboard.
I am trying to get rid of the selectPart() and the subsequent code, unless it turns out to be easier to fix.
The fundamental issue I have is that when the javascript.php runs, it opens the window for the selection and the javascript then completes, reading the clipboard and pushing it to the form (while the popups is still open and the user is making their choice). Subsequent selections, change the clipboard, but they don’t get read until I rerun the popup. I need a way to run the async function which reads the clipboard, either with each selection in the popup, or upon closure of the popup window.
I have tried a variety of things including moving the code to other places, global variables (yuck), and other methods to solve it, so I am hoping for a solution to the original problem.
After a bit of digging, I got rid of the clipboard copy and paste entirely.
Using some standard Javascript between a parent and a child window, I updated the code in the child to reference the parent table directly and dynamically pulling the field names and content from an array:
opener.document.curform[results[2]].value = results[0]
opener.document.curform[results[3]].value = results[1]
for some more information, check out this link: https://www.plus2net.com/javascript_tutorial/window-child3.php
Related
I have a Javascript file running on a page and I would like to log certain events as they occur. For example, I have a web store - and when people add an item to their cart, I want to log this event by visiting a page that I built:
function log_event(id) {
window.location.href = 'https://example.com/log/cart.php?id=' + id;
return false;
}
The log/cart.php page doesn't really have anything to display, all it does is insert a record into a database containing the item that was added to the cart, and the date.
The code that calls this function looks like:
document.getElementById('add-to-cart').addEventListener('click', function() {
// Add to the cart
...
// Track the item that was added
let id = document.getElementById('add-to-cart').getAttribute('data-id');
log_event(id);
});
With my current code, the log/cart.php actually replaces the current page. I want the opening of log/cart.php to only happen in the background without the user being interrupted. I don't want it to actually open a browser tab or window and let the user stay in the product page.
You can send an AJAX request to that endpoint:
function log_event(id) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", 'https://example.com/log/cart.php?id=' + id, true);
xhttp.send();
return false;
}
fetch() can also be used, but be aware of its browser support (no IE).
Is there a way to save a calendar entry by javascript to personal outlook-calendar within a sharepoint-calendar webpart ?
I want to save a created Entry in a sharepoint-calendar direkt to the personal outlook calendar of the user created it.
Any tip how to do this ?
So, the answer is "kind of".
You technically don't have to write JavaScript to achieve this, as SharePoint has a built in service URL that will download an .ICS file to the user's machine, and whatever that user's default calendaring system (e.g. Outlook) will open that as a new Calendar item.
Although you can construct this link manually if you want to provide a calendar item download for one specific Event, you can certainly use JavaScript to dynamically fill in the parameter values in this URL, which may be easier that having to look up these values individually to manually construct a link.
The URL that you can provide a hyperlink to generate an .ics file is
https://**SITE_URL**/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={**LIST_GUID**}&CacheControl=1&ID=**EVENT_ID**&Using=event.ics
SITE_URL – The URL to the site where the calendar is hosted
LIST_GUID – The (guid) unique identifier of your calendar list
EVENT_ID – The (integer) ID of the calendar event
for example:
https://mysharepointserver/sites/myteamsite/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List={B2E3EC57-9BA6-46A2-B072-578C9796A42E}&CacheControl=1&ID=26&Using=event.ics
As an example of who you can use JavaScript to generate this link per event, the following code can be put in a Script Editor WebPart on the same page as a Calendar View Web Part, and it will insert a down arrow character in front of every event link that will trigger the .ics file for that event. This script assumes you have the jQuery library already loaded on your page, and you will need to replace the string "NameOfYourEventsList" below with the actual title of your Events list.
function lookupListBeforeAppendingCalendarLink() {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
list = web.get_lists().getByTitle("NameOfYourEventsList");
context.load(list, 'Id');
context.executeQueryAsync(Function.createDelegate(this,listIdSuccess), Function.createDelegate(this,error));
}
function listIdSuccess() {
var listId = list.get_id();
appendAddToCalendarLink(listId);
}
function error(sender, args) {
console.log('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
function appendAddToCalendarLink(listId) {
jQuery('.ms-acal-rootdiv .ms-acal-item').each(function () {
var currentCalendarAnchor = jQuery('a', jQuery(this));
var itemId = currentCalendarAnchor.attr('href').split('?ID=')[1];
currentCalendarAnchor.before("<a href='" + _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List=" + listId + "&CacheControl=1&ID=" + itemId + "&Using=event.ics'>↓</a>");
});
}
function customizeCalendar() {
//if you know the list id, you can hard code it here,
// otherwise use function to look it up first by List title
// var listId = 'B2E3EC57-9BA6-46A2-B072-578C9796A42E'
// appendAddToCalendarLink(listId);
lookupListBeforeAppendingCalendarLink();
}
ExecuteOrDelayUntilScriptLoaded(customizeCalendar, "sp.js")
I'm redirecting the user from another page when they click the "Edit" button using the code below.
$('#editListButton').click(function(){
window.location.href = "http://localhost/yyy.php"; //redirect
// Changes that need to be made
$('#defaultText').remove();
$('#orderList').append('<p' + 'message' + '</p>');
});
The page redirects to the predefined link, after which I need update a html <div> tag with text. But the code coming from the other page does nothing. How can change the text in the div tag?
Pass it in the url.
$('#editListButton').click(function(){
window.location.href = "http://localhost/yyy.php?message"; //redirect
});
Then on the other page
var url = window.location.href.split('?');
var msg = url[1];
$('#defaultText').remove();
$('#orderList').append('<p>' + msg + '</p>');
Once you've triggered an operation that's going to reload the entire page, browsers (not all, but it seems like most) will just quit doing anything to the current page, essentially ignoring any DOM updates from the event loop.
To get around this, it generally works to delay the redirect with a short timeout:
setTimeout(function() {
window.location.href = "http://localhost/yyy.php";
}, 1);
Now the browser doesn't know that the page is to be reloaded, so it'll obey your DOM update request.
edit — If what you're expecting (and it's not really clear from the OP, but it's hinted at in a comment below) is that the code after updating the location should affect the new page, well that's just not how things work. You can put that code in the new page (and pass parameters via the URL you're loading, if necessary) and have it run there, or else you can change the architecture completely and load your new code via ajax.
There are many ways to pass information from one page to another. To give an idea of the concept, somewhat in relation to the question posted, here's one:
Page A:
$('#editListButton').click(function(){
window.location.href = "http://localhost/yyy.php?action=remove&value=" +
encodeURIComponent('ashdahjsgfgasfas');
});
Page B:
var action = /(?:\?|&)action=([^&$]+)/.exec(location.search)
if ( 'remove' === action[1] ) {
var value = /(?:\?|&)value=([^&$]+)/.exec(location.search)
$('#defaultText').remove();
$('#orderList').append('<p>' + value[1] + '</p>');
}
I have problem where after the page is redirected, I want the select to have the previously selected option as the selected choice after the page has been redirected.
here I have an onchange for my select which will redirect the user depending on their selection(refresh page basically), however after the page refresh the selected option gets reset and the first option in the list get selected.
$("#reportTypes").change(function () {
var reportTypeID = $(this).val();
var deviceTypeID = $('#hDeviceTypeID').val();
window.location.href = "http://127.0.0.1:6543/new_device/" + deviceTypeID + "/" + reportTypeID;
$('#reportTypes').val(reportTypeID);//tried to select the previous option but this doesn't seem to work
});
How can I get my select to display the chosen option without getting reset after the page load?
This is your second question regarding the same problem and I have a strong feeling you don't have a clear picture of what happens where and when. I wish I could give you a link to some "how the Web works" intro, but unfortunately I don't know any. No offense, just saying...
Very briefly, in the context of a Pyramid app, things happen in the following order:
Browser sends a request to the server, which is basically a blob of text
Pyramid application receives and parses the request, and finds a view function to invoke to handle the request.
The view function does some useful stuff, for example it queries data from database and returns a Python dictionary, which Pyramid then passes to the template engine (Jinja2 in your case)
Template engine uses a template (a text blob) and the data returned by your view function to generate another text blob, which represents your rendered HTML page. That blob is then sent to the browser, along with HTTP headers etc. Note that for Pyramid there's actually no HTML, DOM, JavaScript variables or anything like that. Like any web application, your Pyramid app is just a program to receive text blobs and generate other text blobs in response.
Browser receives the server response and interprets it - for example, it may decide that this is an HTML page with some inline <script /> tags. The browser then renders the HTML, loads images and stylesheets, executes scripts etc.
The moment you click on a link or change window.location (let's ignore various AJAX scenarios for the moment) - the moment you do that, the browser abandons your current page and sends another HTTP request (see #1 above). It then waits for the server response and render a completely new page which has absolutely no "memory of" the previous page. This is why HTTP is called "stateless protocol".
My point is: the moment you do
window.location.href = "http://127.0.0.1:6543/new_device/" + deviceTypeID + "/" + reportTypeID;
it makes absolutely no sense to do
$('#reportTypes').val(reportTypeID);//tried to select the previous option but this doesn't seem to work
because the current page is going to be abandoned, a new text blob will be sent from the server and rendered as a new web page.
Now, after this theoretical background, you can see that one of the options to solve your problem would be to send some parameter to the server which would tell it "please give me the same page only with this new reportTypeID pre-selected".
It looks like you already have access to deviceTypeID and reportTypeID in your view function. Now you need to pass them to the template and use them to render selected="selected" attribute on the option which should be pre-selected. In pseudocode it would look something like
%for report_type in all_report_types:
%if report.id == report_type_id:
<option value="${report_type.id}" selected="selected">${report_type.name}</option>
%else:
<option value="${report_type.id}">${report_type.name}</option>
%endif
%endfor
If you are sending the parameters to the same page as GET request parameters and causing a page reload, then you could use JavaScript to parse the url parameters and then set the dropdown to the specified value upon page load.
Taking the function specified by #BrunoLM here for url param parsing: How can I get query string values in JavaScript?
var urlParams = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
Now we execute this function upon page load to grab the values:
//$(function {}); is a shorthand for $(document).ready(function() {});
$(function() {
//execute this code to grab the url params
var urlParams = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
//now we check to see if the parameter was passed and if so, set the dropdown value
if (urlParams['reportTypeId']) {
$('#reportTypes').val(urlParams['reportTypeId']);
}
});
This all assumes that you pass an HTTP GET parameter called reportTypeId like so: "reportTypeId=203"
alright.. i have an input box that captures paste event and checks if the pasted text/string is a youtube url. if yes, it will forward data to some PHP to process..
the result json data is being displayed here $('.printdata').append(response);
concerns:
what i didn't have in my code, is to recognize if the whole text or
the youtube link is removed/cut/deleted. it should also remove the
displayed data.
accept the first youtube URL, if multiple youtube URL is found, send the first link to PHP, then ignore the others, just display it as text.
my workaround
what im thinking (tho not sure) is to put some onchange() event
somewhere to recognize $("$input") element is being changed.
accept only a single paste event and ignore if paste() is repeated. -not sure if this is the right approach.
http://jsfiddle.net/8Pvr4/4/
to test what im trying to explain, input any youtube url in the textfield, and it should display something.
then remove the url, the data remains. OR add another URL consecutively. the resulting data will stack.
$(document).ready(function() {
//some regex
$("#input").bind('paste', function(e) {
var val = undefined;
//get pasted data
if(window.clipboardData && window.clipboardData.getData) {
val = window.clipboardData.getData('Text');
} else if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.getData){
val = e.originalEvent.clipboardData.getData('text/plain');
}
//check for youtube URL
if (youtube.test(val)) {
var yurl = val.match(youtube)[0];
$.post("youtubejson.php?url="+ yurl, {
}, function(response){
$('.printdata').append(response);
});
}
});
I'm not sure i understand your question properly, but i guess your result is stacking and not getting replaced, you can use .html(response) instead of .append(response) to stop stacking.