I'm trying to update a Javascript variable that controls a scrolling script based upon some Ajax code. The Ajax code is supposed to add to the JS Var when conditions are true in the Ajax script. Is there any way to trigger this?
Thanks!
edit: I'm not sure how to change the value of the variable. I've tried changing it via the Ajax but it doesn't get parsed. I've also tried using PHP inside of JS to check a condition, but doing that only works once.
JS Code
function speedUp()
{
actualheight = actualheight + 50;
}
function slowDown()
{
actualheight = actualheight - 50;
}
function ajaxFunction()
{
var xmlhttp = createRequestObject();
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4)
{
document.getElementById('iemarquee').innerHTML=xmlhttp.responseText;
document.getElementById('iemarquee2').innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","saleCallTest.php",true);
xmlhttp.send(null);
}
/*
Cross browser Marquee II- © Dynamic Drive (www.dynamicdrive.com)
For full source code, 100's more DHTML scripts, and TOS, visit http://www.dynamicdrive.com
Modified by jscheuer1 for continuous content. Credit MUST stay intact for use
*/
//Specify the marquee's width (in pixels)
var marqueewidth="500px"
//Specify the marquee's height
var marqueeheight="500px"
//Specify the marquee's marquee speed (larger is faster 1-10)
var marqueespeed=1
//Specify initial pause before scrolling in milliseconds
var initPause=1000
//Specify start with Full(1)or Empty(0) Marquee
var full=1
//Pause marquee onMousever (0=no. 1=yes)?
var pauseit=0
//Specify Break characters for IE as the two iterations
//of the marquee, if text, will be too close together in IE
var iebreak='<p></p>'
//Specify the marquee's content
//Keep all content on ONE line, and backslash any single quotations (ie: that\'s great):
var marqueecontent='<?php for($i=0;$i<=count($saleItems);$i++)
{
if ($saleItems[$i]['stateOfItem'] =="Sold" || $saleItems[$i]['stateOfItem'] =="Unsold")
{
$_SESSION['countItems']++;
echo $saleItems[$i]['itemNumber'];
echo $saleItems[$i]['stateOfItem'] . '<br />';
}};
?>'
////NO NEED TO EDIT BELOW THIS LINE////////////
var copyspeed=marqueespeed
var pausespeed=(pauseit==0)? copyspeed: 0
var iedom=document.all||document.getElementById
var actualheight=''
var cross_marquee, cross_marquee2, ns_marquee
function populate(){
if (iedom){
var lb=document.getElementById&&!document.all? '' : iebreak
cross_marquee=document.getElementById? document.getElementById("iemarquee") : document.all.iemarquee
cross_marquee2=document.getElementById? document.getElementById("iemarquee2") : document.all.iemarquee2
cross_marquee.style.top=(full==1)? '8px' : parseInt(marqueeheight)+8+"px"
cross_marquee2.innerHTML=cross_marquee.innerHTML=marqueecontent+lb
actualheight=cross_marquee.offsetHeight
cross_marquee2.style.top=(parseInt(cross_marquee.style.top)+actualheight+8)+"px" //indicates following #1
}
else if (document.layers){
ns_marquee=document.ns_marquee.document.ns_marquee2
ns_marquee.top=parseInt(marqueeheight)+8
ns_marquee.document.write(marqueecontent)
ns_marquee.document.close()
actualheight=ns_marquee.document.height
}
setTimeout('lefttime=setInterval("scrollmarquee()",20)',initPause)
}
window.onload=populate
function scrollmarquee(){
if (iedom){
if (parseInt(cross_marquee.style.top)<(actualheight*(-1)+8))
cross_marquee.style.top=(parseInt(cross_marquee2.style.top)+actualheight+8)+"px"
if (parseInt(cross_marquee2.style.top)<(actualheight*(-1)+8))
cross_marquee2.style.top=(parseInt(cross_marquee.style.top)+actualheight+8)+"px"
cross_marquee2.style.top=parseInt(cross_marquee2.style.top)-copyspeed+"px"
cross_marquee.style.top=parseInt(cross_marquee.style.top)-copyspeed+"px"
}
else if (document.layers){
if (ns_marquee.top>(actualheight*(-1)+8))
ns_marquee.top-=copyspeed
else
ns_marquee.top=parseInt(marqueeheight)+8
}
}
if (iedom||document.layers){
with (document){
if (iedom){
write('<div style="position:relative;width:'+marqueewidth+';height:'+marqueeheight+';overflow:hidden" onMouseover="copyspeed=pausespeed" onMouseout="copyspeed=marqueespeed">')
write('<div id="iemarquee" style="position:absolute;left:0px;top:0px;width:100%;background:black;color:white;font-size:30pt;">')
write('</div><div id="iemarquee2" style="position:absolute;left:0px;top:0px;width:100%;z-index:100;background:black;color:white;font-size:30pt;">')
write('</div></div>')
}
else if (document.layers){
write('<ilayer width='+marqueewidth+' height='+marqueeheight+' name="ns_marquee">')
write('<layer name="ns_marquee2" width='+marqueewidth+' height='+marqueeheight+' left=0 top=0 onMouseover="copyspeed=pausespeed" onMouseout="copyspeed=marqueespeed"></layer>')
write('</ilayer>')
}
}
}
</script>
AJAX->PHP CODE
<?php
session_start();
//NuSoap Library
require_once('./lib/nusoap.php');
$_SESSION['countTotal'] = 0;
//Creating a Client
$client = new nusoap_client('http://xx.xx.x.xxx:xxxx/WSSERVICE/services/SERVICE?WSDL');
$saleItems= $client->call("getItems", array("Sale" => '001'));
$_SESSION['countNew'] = 0;
$countPresale = count($saleItems);
$timer = $countPresale * 3.15;
for($i=0;$i<=count($saleItems);$i++)
{
if ($saleItems[$i]['stateOfItem'] =="Sold" || $saleItems[$i]['stateOfItem'] =="Unsold")
{
$_SESSION['countNew']++;
echo $saleItems[$i]['itemNumber'];
echo $saleItems[$i]['stateOfItem'] . '<br />';
}};
if($_SESSION['countNew'] < $_SESSION['countVehicles'])
{
$_SESSION['countTotal']--;
}
if($_SESSION['countNew'] > $_SESSION['countVehicles'])
{
$_SESSION['countTotal']++;
}
if($_SESSION['countTotal'] < 0)
{
$opx = 3 * ($_SESSION['countItems'] - $_SESSION['countNew']);
echo 'actualheight = parseInt(actualheight) + parseInt(' . $opx . ');';
$_SESSION['countVehicles'] = $_SESSION['countNew'];
}
if($_SESSION['countTotal'] > 0)
{
$opx = 3 * ($_SESSION['countItems'] + ($_SESSION['countNew'] - $_SESSION['countNew']));
echo 'actualheight = parseInt(actualheight) - parseInt(' . $opx . ');';
$_SESSION['countItems'] = $_SESSION['countNew'];
}
?>
Assuming that the variable is not locked away in a different namespace with no interface made available, then of course.
"Ajax" just means "Fetch some data from the server using JS without leaving the page, then run some JS".
There is nothing special that adds extra limitations to what that JS can do.
I ran into some issues with this as well. Probably namespace problems like another answer here suggests.
Rather than figure out the what/when/why, I just used <input name="blah" type=hidden> and then update that and read that with Javascript:
Then, to write the variable:document.getElementById('blah').value='some new value';
To read the variable: somevar=document.getElementById('blah').value;
That has worked every time. Actually figuring out the correct namespace would be a better option, but this works.
EDIT: Are you using any Javascript libraries to do your ajax for you, or just coding it from scratch? I've used xajax, Prototype, and Jquery for things like this. Jquery is my new baby, but 5 years ago already this was dead simple in xajax.
I'm not sure I want to steer you down that path but for a php programmer, xajax is a pretty simple method to learn. Jquery is more powerful and extensible though in my opinion.
EDIT2: Far as I can tell you are returning both HTML and javascript to be executed in the same response. Including a javascript in your response doesn't make it get executed. Perhaps you should be serializing your return with JSON so you can eval your javascript to be executed, and assign your innerHTML separately.
Just for reference, the same thing you could do in xajax with just:
$objResponse->addAssign("idhere","innerHTML", "some html");
$objResponse->addScript("somvar = somevar + someothervar");
Related
I have a php web page with many informations on it, some of them are quite sensitive and I would like hide them and the possibilty to unhide them.
My web page is built like this to show the informations :
echo '<b>Login :</b> ' . $data['Login'] . '<br \>';
echo '<b>MDP :</b>' . decrypt($data['MDP'], $passkey) . '';
So I'm working on a small Javascript code to hide/show the MDP. It's not finished (cause it work only half), it look like this :
<span class="visible">My text to hide</span><br \>
<span class="visible">My other text to hide</span><br \>
<button id="Replace" onclick="replace()">Change content</button>
<script>
window.onload = function(){
document.getElementById("Replace").addEventListener( 'click', replace);
}
var Visible = document.getElementsByClassName('visible');
var HiddenText = document.getElementsByClassName('hiddentext');
var OriginalText = new Array();
for (var k = 0; k< Visible.length; k++){
OriginalText[k] = Visible[k].innerHTML;
}
function replace() {
if (Visible != null){
for (var i = 0; i< Visible.length; i++){
Visible[i].innerHTML = '*****';
Visible[i].className = 'hiddentext';
}
}else{
for (var j = 0; j< HiddenText.length; j++){
HiddenText[j].innerHTML = OriginalText[j];
HiddenText[j].className = 'visible';
}
}
}
</script>
I don't know why it look like it only work once. It replace the text with the stars and the Class change well but when I use it again, nothing happen.
I tried the code separetely (both part of the if) and all work good.
I'm far from an expert to code so I probably missing something, maybe someone can help me on it.
I finally did it in a different way, instead of replacing the text I just don't show it. I used PHP to hide the text, if you clic on the button the text is shown and after a delay a javascript code will redirect to the same page without the POST information that will automaticaly hide the text again.
function mdpviewer($data){
$ShowMdp = false;
if (isset($_POST['ShowMdp']) AND ($_POST['ShowMdp'] == true) AND ($ShowMdp != true)){
$ShowMdp = $_POST['ShowMdp'];
}else{
$ShowMdp = false;
}
if ($ShowMdp == true) {
return $data;
}else{
echo '';
}
}
echo '<form action="MyPage.php" method="post"><input type="submit" value="Show Passwd"><input type=hidden name="ShowMdp" value="true"></form></div>';
echo'<p>My Password : (mdpviewer($data['Psswd'])</p>';
if (isset($_POST['ShowMdp']) AND ($_POST['ShowMdp'] == true)){
echo '<script>setTimeout(function() { window.location.href = "MyPage.php";}, 30000);</script>';
}
It's probably not optimized and a bit messy but it's working great !
If someone found how to do it with replacing the text on javascript I will be glad to see it
maybe you could apply your logical differently. You could create php files whose purpose is returns data only in json format. This is simutale web service. So, when load page finished, by javascript you could request fetch to .php file endpoint, and manage response and make DOM modifications, another recommendation is you study es6 to do best practices! But is a tip, congratulations for resolve problem and my apologies if my english is bad, but im learning, cheers!
I have an Asp.Net Core MVC application that searches youtube videos and returns a list that is displayed on screen. Each video is placed in a custom component that has a checkbox. Every time a checkbox is selected I access a script that searches all the video components that are on the screen and I store the video id's in a list in my .cshtml page.
At some point I need to get this list of video id's to do a processing. For that I created a javascript method in the same .cshtml page to return this list of ids.
I've already done a research on JSRuntime on Blazor (.razor) pages but that wouldn't be my case.
The fact is that with the click of a button I need to call a controller method, and this method calls my javascript method which returns my list of ids.
How best to do this?
This my javascript code.
#section scripts
{
<script>
var listaDeIds = [];
function Mostrar() {
//document.getElementById("btnplaylist").style.display = 'block';
var videos = document.querySelectorAll('#video');
var count = 0;
var lista = [];
for (var i = 0; i < videos.length; i++) {
//console.log("1 - " + videos.item(i).getAttribute("name"));
var videoID = videos.item(i).getAttribute("name");
//console.log("2 - " + videos.item(i).getAttribute("id"));
const shadow = videos.item(i).shadowRoot;
const childNodes = Array.from(shadow.childNodes);
//console.log("3 - " + childNodes.length);
childNodes.forEach(childNode => {
if (childNode.nodeName === "DIV") {
//console.log("4 - " + childNode.nodeName);
const shadowChilds = Array.from(childNode.childNodes);
//console.log("5 - " + shadowChilds.length);
shadowChilds.forEach(shadowShild => {
if (shadowShild.nodeName === "DIV") {
//console.log("6 - " + shadowShild.nodeName);
const shadowChildsInternas = Array.from(shadowShild.childNodes);
//console.log("7 - " + shadowChildsInternas.length);
shadowChildsInternas.forEach(interna => {
if (interna.nodeName === "INPUT") {
//console.log("8 - Name " + interna.nodeName);
if (interna.checked === true) {
//console.log("9 - Checked: " + interna.checked);
lista[count] = videoID;
count = count + 1;
}
}
});
}
});
}
});
}
if (lista.length > 0) {
document.getElementById("btnplaylist").style.display = 'block';
} else {
document.getElementById("btnplaylist").style.display = 'none';
}
listaDeIds = lista;
}
function RetornaListaDeIds() {
return listaDeIds;
}
</script>
This is my html component code
<custom-iframe id="video" name="#item.Id.VideoId" urlvideo='#Url.Content(item.Url)' onclick="Mostrar()"></custom-iframe>
This is the button that calls my controller.
<div id="btnplaylist" class="right_side hidden">
<button value="Playlist" asp-controller="VideoSearch" asp-action="GravarSelecionados" class="btn green-button button-tamanho-padrao">Playlist</button>
</div>
Code of my control.
I think you might be missing something at a high level here so bear with me.
Your use case is you want users to 'check' videos that you serve to them via a web app, visually altering the page elements around the videos and ultimately sending them off for processing, which I assume means some kind of storage or at least some back-end work.
If I understand your attempted solution to this problem correctly, it is impossible. Even if you did get your backend to run javascript, it wouldn't be aware of the client's state and could not read that list of videos off of it. There's no reason for javascript to run on your server as I see it.
Instead, you need your client-side Javascript to send that list of ids to your server via an API in a JSON format. The flow goes (user checks box -> JS on the browser collects the id of that video and formats a POST request with some json describing what was checked -> that JSON is sent to your server which then reads it an processes it)
The frontend javascript and the server should always communicate with eachother in this way. Again, there's no need for javascript to be run on the server itself.
Moving on to thank everyone who gave suggestions for solving my problem for their support. I followed and tested all the suggestions and the one that fit best to my problem was the use of ajax, suggested by #Andre.Santarosa.
I followed the following article as a reference:http://www.macoratti.net/15/05/mvc_ajax.htm
I installed the package: Microsoft.jQuery.Unobtrusive.Ajax
I added the script reference in my _Layout.cshtml:
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
On the page that lists the videos, the code looks like this:
Button code:
<div id="btnplaylist" class="right_side hidden">
<input type="button" value="Playlist" id="Playlist" class="btn green-button button-tamanho-padrao" />
</div>
Ajax Code:
$('#Playlist').click(function () {
var url = "/VideoSearch/PegarListaDeIds";
var lista = listaDeIds;
$.post(url, { pListaDeIds: lista }, function (data) {
$("#msg").html(data);
});
});
I am trying to add create an editable table in HTML. So, I need to add rows, when user clicks on a button. Here is the code I am using.
//remove all old rows.
while (summaryTableElement.firstChild) {
summaryTableElement.removeChild(summaryTableElement.firstChild);
}
//add a new text area in the summary field.
summaryTableElement.innerHTML = "<textarea id='summaryTextBox' value='' onblur='saveSummary()'> </textarea> ";
This code works fine on Chrome and Mozilla. But, IE doesn't allow editing innerHTML. This HTML will be displayed inside a VB form, so I have "browser" and "webbrowser" controls available. Both of those controls use IE engine, so this code does not work there.
I have tried using firstchild.innerHTML instead so that I am not editing table row directly, and even that gave me same error.
I tried using WebKitBrowser. But, that causes an exception on load. Apparently that control uses some old method, and the method is changed. So, that control is out of question too.
Now, I am confused as to how to solve this problem?
Edit:
I found the issue with WebKitBrowser. It was specific to x86, while my project was targeting both x64 and x86. Switching it to x86 for both, worked. Although, webkit browser do not take return key values. So, I have a new problem. Pressing enter does not create a new line in table cell, and instead passes the event to vb form.
Edit:
Okay, so I tried working further with WebKitBrowser. But, that control gives me accessviolatedexception. So, I am thinking about going back to using the default browser control, for now.
As for default control, I checked further. Apparently, code works fine in IE9 and above. But, vb.net control uses some weird JS engine. So, I am receiving error only in vb control.
Here is the complete code for reference:
var summaryChanges = "";
var isSummaryClickable = true;
//creates a textbox for editing purpose and include the original summary data.
function modifySummary(id) {
var summaryTableElement; //to get the table cells so that we can access the value
var originalSummary = ""; //to hold the original summary while we create a text box
var loopCounter = 0;
if (isSummaryClickable == true) {
isSummaryClickable = false; //saves event spilling when clicked on the newly created textbox
//get the summary table id saved.
summaryTableElement = document.getElementById (id).childNodes.item(0);
//add existing data to a string to save it for later.
for (loopCounter = 0; loopCounter < summaryTableElement.childNodes.length; loopCounter++) {
originalSummary = originalSummary + summaryTableElement.childNodes.item(loopCounter).childNodes.item(0).innerHTML + "\n";
}
//remove all old rows.
while (summaryTableElement.firstChild) {
summaryTableElement.removeChild(summaryTableElement.firstChild);
}
//add a new text area in the summary field.
summaryTableElement.innerHTML = "<tr><td><textarea id='summaryTextBox' value='' onblur='saveSummary()'> </textarea></td></tr> ";
//set the width of the textbox to allow easy modification
document.getElementById("summaryTextBox").style.width = '600px';
//add original summary text to the text area and set focus
document.getElementById("summaryTextBox").value = originalSummary;
document.getElementById("summaryTextBox").focus();
}
}
// saves the updated summary data back to HTML
function saveSummary()
{
var newHTML = "";
var changesSummary;
var changesSubString = new Array();
var index = 0;
var elementToUpdate;
//get the summary table id saved.
elementToUpdate = document.getElementById("SummaryData"); //.childNodes.item(0);
//get changes from the textbox
changesSummary = document.getElementById("summaryTextBox").value;
//generate string array for separate lines from summaryChanges
changesSubString = changesSummary.split("\n");
//generate new HTML string for the summary fields
//alert(changesSubString.length);
for (index = 0; index < changesSubString.length; index++) {
newHTML = newHTML + "<tr><td class='Text' style='padding-left: 4px;padding-bottom: 4px;' id='SummaryLine" + index + "'</td>" + changesSubString[index] + "</tr>"
}
//update the HTML to the element
elementToUpdate.innerHTML = newHTML;
//allow clicking on summary table
isSummaryClickable = true;
}
function doNothing(id) {
//empty function for future use
return;
}
//this function is called from vb.net script to read the js variable.
//do not change the function definition (name or parameters or return type)
//any change will cause error in vb.net script
function jsInvokedFunction() {
var updatedHTML; // to be used by vb.net invoked function to get updated body
var testVariable = "test";
updatedHTML = document.body.innerHTML.toString();
return updatedHTML.toString();
}
I receive an error at the start of the line summaryTableElement.innerHTML = " ";
It is possible I am missing some other error, but I couldn't find any.
<input type="button" onclick="restartBattle('Battle=Trainer&BattleID=294','nFOgYlQGjn')" value="Restart Battle" style="width:160px;">
That is the coding of the button. Unless the restart code is entered as well (it's dynamic, changes every refresh), I can't click the button with the methods of Javascript or jQuery that I've tried.
'nFOgYlQGjn' is the restartCode. I've tried this coding to click the button, but it won't work.
var btn = document.querySelector('input[value="Restart Battle"]');
if (btn) {
var x = Math.round((Math.random() * 90) + 663);
var y = Math.round((Math.random() * 15) + 589);
function restartBattle(url, restartCode) {
$('#battleContent').html('Loading...<br /><br />');
$('#battle').load('http://tpkrpg.net/core/battles/battle.php?'+url+'&RestartCode='+restartCode);
}
//btn.click();
}
This should work, since I took the function restartBattle part out of the source code, but it still won't work. Any ideas?
Pass the data as an object to the script. You could use on('click', method here) or click(method here) on the id of the input tag. Make sure jquery is included too.
button:
<input type="button" value="Restart Battle" id="restart" />
css:
#restart
{
width:160px;
}
jQuery:
/* sample how to get the values as variables
method one, static hard coded
var battleType = "Training";
var battleId = 294;
var restartCode = "nFOgYlQGjn";
method 2, php set via echo, requires page to be created by php, example uses theoretical data returned from a database stored as an associative array but could be changed for variables
var battleType = <?php echo $battle['training']; ?>;
var battleId = <?php echo $battle['id']; ?>;
var restartCode = <?php echo $battle['restart_code']; ?>;
*/
function restartBattle( varz )
{
$("#battleContent").html("Loading...<br /><br />");
$("#battle").load("http://tpkrpg.net/core/battles/battle.php", {Battle : varz.data.type, BattleId : varz.data.id, RestartCode : varz.data.code});
}
// handle the click of the button and execute functon with passed data.
$("#restart").on("click", { type : "Training", id : 294, code : "nFOgYlQGjn" }, restartBattle);
Your php code needs to check for this data being passed to it so it can return the data either some json, html, or plain text using echo.
battle.php:
$restartCode = ( ( isset( $_REQUEST['RestartCode'] ) ) ? $_REQUEST['RestartCode'] : false );
if( !$restartCode ) echo "Error : No restart code!";
That is a start, but you need to create variables that hold the data being sent to the php script or else it's hard coded to those values.
See method API
I am using the replaceWith() function in jQuery to update my web page. I receive the data from a C# web service program that extracts data from a database to build my HTML code. It works fine except when I replace large amounts of data. In the example that's not working, I replace code in my web page with 39000 bytes of data. After that, none of my links work when clicking on a span to calls a JavaScript function. Is there a limit on the size of data used in the replaceWith() function? The html code I am replacing looks like this:
<td align=left valign=top>
<div id="showitems" class="showitems" style="display:inline; float:left"></div>
</td>
The javascript code looks like this:
function ShowDinerItems() {
var gps = document.getElementById("selectdiner").value;
var pos = gps.indexOf(";");
var len = gps.length;
var latitude = document.getElementById("Hiddenlat").value;
var longitude = document.getElementById("Hiddenlng").value;
var dinerkey = gps.substring(0, pos);
PageMethods.CallShowDinerItems(dinerkey, latitude,longitude, OnShowDinerComplete, OnShowDinerError, dinerkey);
}
function OnShowDinerComplete(result) {
var htmlcode = result[0];
if (result == 'none') {
document.getElementById("Message").value = "Search returned no items";
}
else {
var htmlcode = result[0];
htmlcode = "<div id=\"showitems\" class=\"showitems\" style=\"display:inline\">" + htmlcode + "</div>";
$('.showitems').replaceWith(htmlcode); // size of htmlcode is 39849 bytes
var locations = result[1].split(";");
var lat = locations[0];
var lng = locations[1];
markDiner(lat, lng, "", 'map_canvas');
}
}
The reason I am using jquery to build my webpage is to avoid page reloads. I could easily program the webdata content in my C# program which may be more efficient but page reloads are to be avoided as dictated by the people who own the website. I am will try the recommendations given.
Note: I used the following code to make it work.
$('.showitems').html(result[0]);
Using .text will not work as it displays raw data and not html data. Thanks to those who contributed.
To be honest I think you're going about this the wrong way here.
It seems to me that you're using ReplaceWith to completely overwrite the matched tag when you could just as simply change its properties with jQuery.
For example:
var htmlcode = result[0];
htmlcode = "<div id=\"showitems\" class=\"showitems\" style=\"display:inline\">" + htmlcode + "</div>";
$('.showitems').replaceWith(htmlcode); // size of htmlcode is 39849 bytes
Could easily be changed to this:
$('.showitems').css('float','none').text(result[0]);
Just how many showItems are there going to be by the way, and how do you know how it compares to how many results you get back from the C# call ?
Edit 2: Sorry, didn't realise that the CSS display attribute wasn't actually changing.