Entire page markup is replaced on AJAX request - javascript

When i call my function in my js.erb template it replaces the entire page rather than just the div that i indicate. Can anyone help?
remove.js.erb
$('div.mini-basket-wrapper').html("<%= j(render 'shop/baskorder/mini_basket') %>");
#This replaces the page completely
$('#basket-info').load(document.write(basket_text()));
view
<div id="basket-info">
<div id="basket-amount">
<div class='mini-basket-icon'>
<%= image_tag 'shop/icons/basket.svg', alt: '' %>
</div>
<script type='text/javascript'>
document.write(basket_text());
</script>
</div>
</div>
JS
function fc_basket_text_from_cookie(empty_text, normal_text)
{
var basket = readCookie('bk');
if (basket)
{
var parts = decodeURIComponent(basket.replace(/\+/g, '%20')).split('|')
if (parseInt(parts[1]) == 0)
return normal_text.replace(/##VALUE##/g, parts[0]).replace(/##ITEMS##/g, parseInt(parts[1]));
// return empty_text
else
return normal_text.replace(/##VALUE##/g, parts[0]).replace(/##ITEMS##/g, parseInt(parts[1]));
} else {
return '';
}
}
var emptyBasketHTML = "<span class='header_text'>Items in basket: 0 Total: £0.00</span>";
function basket_text(){
var populated = "<span class='header_text'>Items in basket: ##ITEMS##</span><span class='header_text'>Total: ##VALUE##</span>";
//populated += "<input type='submit' value='Checkout' name='commit' class='go_botton header-checkout-button'>"
return fc_basket_text_from_cookie(emptyBasketHTML,populated);
}

Reading here: Using document.write.
When the page finishes loading, the document becomes closed. An attempt to document.write in it will cause the contents to be erased.
Further the .load() function is used to load data from a server. I believe you want the .html function.
[Untested] Change the line $('#basket-info').load(document.write(basket_text()));
To $('#basket-info').html(basket_text());

Thanks for all the input. Realised what i was doing wrong and decided to add an ajax on success to my js file:
$(document).on('ajaxSuccess', function(){
$('#basket-amount-info').html(basket_text());
});
Added this id #basket-amount-info to contain the script in the view.

Related

Using Scriptlet code inside frontend javascript functions

im a student, not too experienced with coding. trying to make a software solution for my class, and having some problems with running <%...%> tags inside functions that are in tags in an ejs HTML file.
<script>
//grab elements
const textBox = document.querySelector(".lineBox");
const nextLine = document.querySelector(".nextLine");
const prompt = document.querySelector(".question");
//display starting script line
textBox.innerHTML = "<%= JSON.stringify(scripts[scriptName][counter][0]) %>";
//nextline function
function updateLine() {
<% counter = counter + 1; %>
if ("<%= JSON.stringify(scripts[scriptName][counter][0]) %>" == 1) {
<% counter = counter + 1; %>
}
textBox.innerHTML = "<%= JSON.stringify(scripts[scriptName][counter][0]) %>";
}
//prompt line function
function promptLine() {
<% counter = counter + 1; %>
textBox.innerHTML = "<%= JSON.stringify(scripts[scriptName][counter][0]) %>";
}
//call functions onclick
nextLine.onclick = updateLine;
prompt.onclick = promptLine;
</script>
I am currently making a website that displays lines off a script for actors to learn. The problem is that the scriptlet tags are running regardless of the functions. My first thought was to put the whole function inside scriptlet tags, but unfortunately that means that I cant use the variables from the frontend ejs file like textBox and prompt inside those tags because that runs in the server side.
I don't have a lot of knowledge about this so I'm sure I'm wrong on something here. Any tips?

How to reload Laravel #includes with AJAX?

I've got a single page application inside of my larger application that will send data to the DB, and will also display that same table's data. Currently, I have AJAX dynamically sending the data. However, to get the data just inserted to appear in the table that I want it to, I have to refresh. I've been trying things all morning, but below is the current state of things.
The View:
<html>
<head>
<!--I took some stuff out to make it easier to look at -->
</head>
<body onresize="resizeRecalc()">
<div class="container-fluid">
<div class="row header">
<div class="col-12">
<img src="{{ URL::asset('images/takeStatsLogo.png') }}" id="header-logo" />
</div>
</div>
<div class="mainArea row">
<div class="left col-8">
<div onclick="playPause()" class="embed-responsive embed-responsive-16by9">
<video id="gameFilm" src="{{ URL::asset('images/basketball.mp4') }}" preload="metadata"></video>
</div>
<div class="timebar">
<span class="timeItem" id="timestamp"></span>
<div onclick="changeVidTime()" onmousemove="moveLine(event)" onmouseout="REmoveLine()" id="outerBox"> <div id="progressBox"> <div id="placeMarker">
</div></div></div>
<span class="timeItem" id="duration-place"></span>
</div>
<!-- This is a key part -->
<div id="statList">
#include('partials.statList')
</div>
</div>
<div id="right" class="right col-4">
<!--Checking if we should make the user select starters. If we have them, no need to do that...-->
#if ($game->starters != null)
#include('partials.areStarters')
#else
#include('partials.noStarters')
#endif
</div>
</div>
</div>
<script>
//Add Stat Form
//This part here will add the stats, but it won't refresh them!
$('input#addStatButton').click( function() {
$.post( '{{action("StatController#store")}}', $('form#new_stat').serialize(), function(data) {
$('#statList').load('/take-stats/{{$game->id}}');
},
'json' // I expect a JSON response
);
clearStat();
});
</script>
<script src="{{ URL::asset('js/takeStats/genJavascript.js') }}"></script>
<script src="{{ URL::asset('js/takeStats/videoJS.js') }}"></script>
<script src="{{ URL::asset('js/takeStats/dataJS.js') }}"></script>
</body>
</html>
Here is the controller method:
public function loadStatList($id) {
$userType = Auth::user()->user_type;
if(Auth::check() && Game::where('id', '=', $id)->exists() && ($userType == 'statistician' || $userType == 'admin')) {
$game = Game::find($id);
$players = $game->team->users->where('user_type', 'player');
$stats = Stat::orderBy('video_timestamp', 'desc')->where('game_id', $game->id)->get();
$statMeta = Stat_Meta::all()->where('type', 'recorded');
return view('partials.statList', compact('game', 'players', 'stats', 'statMeta'));
} else {
abort(404);
}
}
I might be missing something but I thought this would do what I am trying to achieve.
I figured it out!Thank #Get Off My Lawn for giving me a bit of a hint that I couldn't just use the #include. I went ahead and figured out how to pre-render the HTML and then bring it in. It is actually not that hard. The idea here is to use a JQuery function to do an AJAX POST upon hitting submit, then use .done to get then new full webpage. After you have that (you can console.log it to see what you're working with at that point, it will be the entire webpage) you can just get the specific div you want to refresh from the .get you performed, and stick it in the same div. Here is the code:
HTML/#include:
<div id="statList">
#include('partials.statList')
</div>
The AJAX/JQuery:
$('input#addStatButton').click( function() {
$.ajax({
type: 'POST',
url: '{{action("StatController#store")}}',
data: $('form#new_stat').serialize(),
})
.done(function(refresh) {
clearStat();
$.get('{{action("StatController#show", [$game->id])}}', function(data) {
var newData = $("#statList" , data)
$( "#statList" ).html( newData );
//console.log(newData);
});
});
});
I'M SO HAPPY Y'ALL!!!
As discussed this is not an answer on your question but a simple explanation you asked in the comments. And it can help somebody else
Laravel and JQuery
How powerfull :-)
First i will try to fit this as much as possible to your needs with the information your provided.
Secondly jquery contains some cool ass functions a lot of people don't know about.
As you described you have a single page website or something like that. That means you have 1 route to show the single page i suggest /take-stats/{{$game->id}}.
In your controller and i use as example the GameController you have something like the following.
class GameController
{
public function __construct()
{
}
//the single page view
public function index()
{
//your singlepage logic here....
return view('games.index'); //something like this?
}
public function create() //this is where you post to
{
//logic to store the game stats...
//this is where you return a succes message or something.
//lets return the index instead :-)
//dont't return $this->index! use redirect to the route.
return redirect()->route('the.route.to.your.index');
}
}
As you see above, we return the single page in the post response. SSo when you post to the store method, and it succeeds it returns the index page.
Now the jquery.
$('input#addStatButton').on( function() {
//this is where to do the post.
$.post(`{{ route('to.your.store.route') }}`, $('form#new_stat').serialize(), (response) => {
//clear the stats because the post is succeeded in here
//also reload the content. The response contains the new html content
//now what we can do is replace the whole content....
//something like $(`html`).html('response);
//or we get the content we need from the response and this is where jquery comes in handy. The response is simply a html response so jquery can create a new dom from it.
let statsList = $(response).find(`#statslist`).html(); //create a dom element of the response.
$(`#statslist`).html(statslist); //put the filtered html in the current list.
//thats all :-)
}).fail(() => {
// a fail save. When the post fails it will come in here.
}).always(() => {
clearStats();
//this is called always even when it fails. You can clear the stats or something in here.
});
});
A short description :
Onclick post button, post to post.route
Controller method does logic and returns as success the index url.
jquery parses the html response and replaces the original content.
done.
I hope this helps you or somebody else. When using a structure like above this code is simply cleaner and faster for it only executes one request.

javascript loading sequence

I have a MainView "About.cshtml" it has a script tag in it and a partial view.
<script>
$(function () {}
</script>
<div>
#Html.Partial("~/Views/Maps/_MapDetailsList.cshtml", Model.saVM)
</div>
Inside "_MapDetailList.cshtml" partial view i am referencing another script ge.js
#Scripts.Render("~/Scripts/ge.js")
<table id="MapDetails">
.....
<tr><th>
<script>setGrowthArray(1, 1);</script>
</th></tr>
</table>
ge.js
var dictionaryGrowth = new Array();
function setGrowthArray(colIndex, mapDetailId) {
//making a sparse array
dictionaryGrowth[colIndex] = mapDetailId;
}
Now i want to send this dictionaryGrowth array to server side after the page/table is loaded
so i did the following in the About.cshtml script but didnot work..
<script>
$(function () {
$("#MapDetails").load(function () { alert("everything seems fine");});
}
</script>
Also please tell me what will be the script and DOM loading sequence in my case.
UPDATE
Probably the Current sequence is
Script on About.cshtml is executed
ge.js is executed
document.ready inside partial view is fired
javascript function (setGrowthArray) from inside DOM is called
Now i want to call my controller??
If i write window.onload = ... inside ge.js it is never fired
You can substitute using $.post() for .load(), pass result of setGrowthArray(1, 1) as data posted to server
<script>
$.post("/path/to/server", {growth:setGrowthArray(1, 1)}, function(data) {
console.log(data); // response from server
$("#MapDetails").html(data);
})
</script>

adding piece of HTML code using JS based on URL accessed

What I am trying to achieve is if a particular page is loaded in the browser for e.g www.domain.com/page then the following piece of code should be added in the page dynamically using JS (similar to how we load the Google Analytics code)
<div id="something">
<img src="http://domain.com/images/someImage.jpg">
</div>
I am trying to figure the script which will load the above mentioned HTML code (anywhere of the page - www.domain.com/page)
Edit 1:
what I am trying to achieve is when the user goes to www.domain.com/page.html I am calling another page lets say page1.html which should contain the script which insert the HTML code I posted above. So I simply want to insert the function which should be enclosed in the tag inside page1.html. Unfortunately I can not edit www.domain.com/page.html
If you want to PLACE that code anywhere in your page using javascript, you first need to identify that PLACE in DOM Using an "id" attribute. Here's an example:
HTML:
<html>
<body>
<div id="target1"></div>
<div id="target2"></div>
</body>
</html>
JS:
var html = '<div id="something"><img src="http://domain.com/images/someImage.jpg"></div>';
document.getElementById('target1').innerHTML = html;
document.getElementById('target2').innerHTML = html;
You can try something like this :
$(document).ready(function () {
var url = window.location.href;
$("#something").append("<img src='"+ url +"' />");
});
$(".documentholder").load("code.html");
If you a specific id of something
$(".documentholder").load("code.html #someid");
If you a specific tag and id of something
$(".documentholder").load("code.html #someid");
Here you are,
just change this part if (getFileName() == "js") with if (getFileName() == "page")
I added js because that is what is returning in the code snippet :)
function getFileName() {
var url = document.location.href;
url = url.substring(0, (url.indexOf("#") == -1) ? url.length : url.indexOf("#"));
url = url.substring(0, (url.indexOf("?") == -1) ? url.length : url.indexOf("?"));
url = url.substring(url.lastIndexOf("/") + 1, url.length);
return url;
}
var div = '<div id="something"><img src="http://domain.com/images/someImage.jpg"></div>';
if (getFileName() == "js") {
$('body').append(div);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
let's say you save this code in a html-file named something.html
$(".documentholder").load("something.html");
in this case the class "documentholder" is the container you put the code in

How to trigger else clause in an onload event?

I have the Comments handle in my Google App Engine app to display the comments. I want to stop the page from loading if the user (defined as "chooser" here) is not in localStorage.
I get the first 2 alerts: "load event" and chooser: "undefined". Since "chooser" is undefined I expect the else clause to trigger but I don't get the alert in else clause.
Also, the first item in ordered list is displayed but not the rest. So I assume there is an issue with loading of the page. How can I fix this?
class Comments(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head>
<title>Choices</title>
<script type="text/javascript">
function showChoices ()
{
alert("load event");
var chooser = localStorage.getItem("chooser");
alert("chooser: " + chooser);
if (chooser)
{
document.getElementById("topten").style.display="inline";
}
else
{
alert("else triggers");
document.write("get an invitation");
}
}
window.onload = showChoices;
</script>
</head>
<body>
<div class="content">""")
#python code:
query = Users.all()
e = query.fetch(10)
self.response.out.write("""<ol>""")
for item in e:
self.response.out.write("""
<div id="topten" class="title" style="display:none">
<li>%s (<span class="small">%s</span>)</li>
</div>
<hr><br />"""
% tuple([item.choice, item.owner]))
self.response.out.write("""</ol>""")
self.response.out.write("""
</div>
</body>
</html>""")
Are you sure that chooser is undefined and not the string literal "undefined"?
see this fiddle i made

Categories

Resources