$(document).ready(function() {
var page = 1;
var notEOF = true;
var client = new XMLHttpRequest();
var temp = "string";
client.open('GET', '/blog/blogdata.txt');
client.onreadystatechange = function() {
if (client.responseText != '') {
var txt = client.responseText.split("\n");
if (notEOF && txt[page * 6 - 6] != "EOF") {
var data = txt[page * 6 - 6].split("#");
document.getElementById("link1").setAttribute("href", data[0]);
document.getElementById("image1").setAttribute("src", data[1]);
document.getElementById("title1").innerHTML = data[2];
document.getElementById("text1").innerHTML = data[3];
document.getElementById("tags1").innerHTML = data[4];
document.getElementById("date1").innerHTML = data[5];
} else {
notEOF = false;
$("#article1").hide();
}
}
}
var blog_html = "/blog/page";
document.getElementById("prev").setAttribute("href", blog_html.concat((page - 1).toString()));
document.getElementById("next").setAttribute("href", blog_html.concat((page - 1).toString()));
if (page == 1) {
$("#prev").addClass("disabled tm-mr-20");
}
if (page == 2) {
document.getElementById("prev").setAttribute("href", "/blog/");
}
if (!notEOF) {
$("#next").addClass("disabled tm-mr-20");
}
client.send();
});
<script src="/blog/js/jquery.min.js"></script>
<script src="/blog/js/templatemo-script.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
This is a simplified version of a script I wrote in my blog html file to automate the blog part.
blog/blogdata.txt is a textfile consisting of lines of the form url#image url#title#text#tags#date, with the last line as just EOF. (If necessary, I can restructure this). This is the structure of a blog post (ripped from here)
<article class="col-12 col-md-6 tm-post" id="article1">
<hr class="tm-hr-primary">
<a href="post.html" class="effect-lily tm-post-link tm-pt-60" id="link1">
<div class="tm-post-link-inner">
<img src="/blog/img/img-01.jpg" alt="Image" class="img-fluid" id="image1">
</div>
<h2 class="tm-pt-30 tm-color-primary tm-post-title" id="title1">Simple and useful HTML layout</h2>
</a>
<p class="tm-pt-30" id="text1">
There is a clickable image with beautiful hover effect and active title link for each post item. Left side is a sticky menu bar. Right side is a blog content that will scroll up and down.
</p>
<div class="d-flex justify-content-between tm-pt-45">
<span class="tm-color-primary" id="tags1">Travel . Events</span>
<span class="tm-color-primary" id="date1">June 24, 2020</span>
</div>
</article>
And this is the structure of the previous and next buttons
<div class="row tm-row tm-mt-100 tm-mb-75">
<div class="tm-prev-next-wrapper">
Prev
Next
</div>
</div>
There's obviously more to the script (if there's anything necessary I'm omitting, I'll add it) but this is the important part of it.
I'm trying to run the file but it's not functioning as intended (currently, the blogdata.txt file has one non-EOF line, and thus the blog should contain exactly one post. Instead, it contains none). When I added alerts to try to debug, I observed that this script is being called twice. Why?
In your case
client.onreadystatechange = function() {
if (client.readyState === XMLHttpRequest.DONE && client.responseText != '') {
but this is better
client.open('GET', '/blog/blogdata.txt');
client.onload = function() { ... }
client.send()
Since you have jQuery
$(function() {
var page = 1;
var notEOF = true;
var temp = "string";
$.get('/blog/blogdata.txt', function(responseText) {
if (!responseText || responseText.toString().trim() === "") return
const txt = responseText.split("\n");
...
});
});
Related
I am using Js xmlHttpRequest to display the same menu on different pages of my site. Lately I found out that some functions are not executed when the site is online, like a quiz I made.
I had also tried to use fetch, or put the scripts in different files, but the same thing kept happening.
(The quiz does work when checking locally, where the xml request cannot be satisfied.)
//load the menu
onload = function loadXMLDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementsByTagName('body')[0].innerHTML +=
this.responseText;
}
};
xhttp.open("GET", "mnu.html", true);
xhttp.send();
}
//check the quiz
const checkBtn = document.getElementById('checkBtn')
checkBtn.onclick = function quizCheck() {
//right answers
var score = 0;
if (q1a1.checked) {
score = score + 1;
}
if (q2a1.checked) {
score = score + 1;
}
alert("your score: " + score);
}
<li>
Check the right answer:
<br>
<input type="checkbox" id="q1a1">Right
<br>
<input type="checkbox">Wrong
</li>
<li>
Check the right answer:
<br>
<input type="checkbox" id="q2a1">Right
<br>
<input type="checkbox">Wrong
</li>
<button id="checkBtn">Check</button>
Anybody knows why and/or has some solutions?
The problem is this line which is wrong and that's why js is not working.
document.getElementsByTagName('body')[0].innerHTML += this.responseText;
You can't just add to innerHtml like that.
Instead you should create an html element and add it to body like this:
if (this.readyState == 4 && this.status == 200) {
var p = document.createElement("p");
p.innerText = this.responseText;
document.body.appendChild(p);
}
edit: of course you want to add an html menu instead of just a text inside a <p>, so you will have to add it like this:
var nav = document.createElement('nav');
nav.innerHTML = this.responseText;
document.body.prepend(nav); // always at the top
I have written the jquery to create a web part zone for every tab in a page layout.The tabs have come and there is a web part zone but it is not working and the web part zone is also viewable before editing page.
<script>
$( document ).ready(function() {InsertTabs();});
function InsertTabs(){
var val=["Tab1","Tab2"];
var attrID = "";
var activeTabFade = "";
var activeTabVar = "";
var index = 0;
for(value in val){
var title = value;
if(index == 0) {
activeTabFade = "in"; activeTabVar = "active";
}
$("#TopSPTabs").append('<li class="'+activeTabVar+'">'+title+'</li>').after('<div class="tab-pane fade '+activeTabFade+ ' ' +activeTabVar+'" id="Tab'+index+'"></div>');
var webPart = '<div class="ms-SPZoneLabel"><span class="ms-webpart-zone-title ms-noWrap">Zone 1</span></div><div ondragenter="MSOLayout_MoveWebPartDragZoneEnter(this, event);" ondragover="MSOLayout_MoveWebPartStopEventBubble(event);" class="ms-SPZone ms-webpart-zone ms-fullWidth " id="MSOZone" zoneID="g_74D304E354064D6780C33FA9DE8BF9A2" zoneTitle="Zone 1" orientation="Vertical" onclick="WzClick(event, 'g_74D304E354064D6780C33FA9DE8BF9A2')" cellspacing="10px" class="ms-webpart-zone ms-fullWidth"><div orientation="Vertical" ondragenter="MSOLayout_MoveWebPartDragEnter(this);" ondragover="MSOLayout_MoveWebPartDragOver(event, this, "False");" style="vertical-align:top;width:;min-width:;padding:8px;"><div class="ms-SPButton ms-WPAddButton" onclick="CoreInvoke('ShowWebPartAdder', 'g_74D304E354064D6780C33FA9DE8BF9A2');return false;"><span>Add a Web Part</span></div></div><div orientation="Vertical" ondragenter="MSOLayout_MoveWebPartDragEnter(this);" ondragover="MSOLayout_MoveWebPartDragOver(event, this, 'False');" align="center" valign="middle" id="MSOZone_EmptyZoneCell" data-iszonecell="true" style="height:10px;padding:0;"> <span class="ms-spzonecaption" name="MSOZoneCell_emptyZoneText" webPartsInZone="0"> <br></span></div></div>';
$("#Tab" + index).append((webPart));
activeTabFade = "";
activeTabVar = "";
index++;
}
}
</script>
<style>.tab-content{margin-top:10px;} .tab-pane{margin-top:0 !important;}</style>
<div class="tab-content" id="tabContents"><ul id="TopSPTabs" class="nav nav-tabs"></ul></div></div><div class="ms-clear"></div>
The page with the created page layout in edit mode.
The page with created page layout without edit mode.
This may be extremely simple, but my brain's just not grasping this for some reason.
I'm making a Tic-Tac-Toe/Hollywood Squares game, and all the square variables are set to null
square0Value = "";
square1Value = "";
etc.
When you click on one of the squares, it launches a bootstrap modal with a closeup of the square and two buttons, X and O, and passes all of the data from the grid square into the modal, so that I only need one modal markup block.
When you click the X or the O, I need it to dynamically set the square variable, that is associated with the modal to either X or O, once the modal is closed, another javascript function checks all the variables to see if there's a 3-in-a-row occurrence, and displays a console.log that X or O has won the game. But I'm not writing this correctly, and none of the square variables are being set.
Here's my code:
HTML:
<button class="squareButton" data-toggle="modal" data-target="#squareModal" data-square="" data-nameplate="" data-xo="" data-id="square0">
<div class="xo"></div>
<div class="nameplate"></div>
<div class="desk"></div>
</button>
(I have this replicated 9 times.)
[Modal markup]
<div class="modal fade-scale" id="squareModal" tabindex="-1" role="dialog" aria-labelledby="squareModal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="square">
<div class="squareModal">
<div class="xo"></div>
<div class="nameplate"></div>
<div class="desk"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" id="modalX" class="btn btn-default btn-xo" data-dismiss="modal">X</button>
<button type="button" id="modalO" class="btn btn-default btn-xo" data-dismiss="modal">O</button>
</div>
</div>
</div>
</div>
JS:
I have an array built that populates each square with a celebrity/personality, and an document.ready function that shuffles the array populates the squares:
$(document).ready(function(){
shuffle(squares);
for (i = 0; i < 9; i++) {
$("#square"+i).find('.squareButton').addClass(squares[i][0]);
$("#square"+i).find('.squareButton').data("square", squares[i][0]);
*// the [0] block of the array is a class filler*
$("#square"+i).find('.squareButton').data("nameplate", squares[i][1]);
*// the [1] block of the array is the celebrity's name*
$("#square"+i).find('.nameplate').html(squares[i][1]);
}
});
var square0Value = "";
var square1Value = "";
var square2Value = "";
var square3Value = "";
var square4Value = "";
var square5Value = "";
var square6Value = "";
var square7Value = "";
var square8Value = "";
var squareClass = "";
var squareName = "";
var squareXO = "";
var squareId = "";
$('#squareModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
squareClass = button.data('square');
squareName = button.data('nameplate');
squareXO = button.data('xo');
squareId = button.data('id');
console.log(squareId);
var modal = $(this)
modal.find('.modal-body').addClass(squareClass);
modal.find('.modal-body .nameplate').html(squareName);
modal.find('.modal-body .xo').html(squareXO);
})
$('#squareModal').on('hidden.bs.modal', function (event) {
var modal = $(this);
modal.find('.modal-body').removeClass(squareClass);
checkWin();
});
function clickX(){
$(eval(squareId+'Value')).val("X");
$(eval(squareId)).addClass('selected');
$(eval(squareId)).find(".squareButton").data("xo", "X");
$(eval(squareId)).find(".xo").html("X");
}
function clickO(){
$(eval(squareId)).addClass('selected');
$(eval(squareId+'Value')).val("O");
$(eval(squareId)).find(".squareButton").data("xo", "O");
$(eval(squareId)).find(".xo").html("O");
}
$("#modalX").on("click", function(e){
e.preventDefault();
clickX();
});
$("#modalO").on("click", function(e){
e.preventDefault();
clickO();
});
function checkWin() {
for (i = 0; i < 9; i++) {
console.log("Square"+i+": " + eval('square'+[i]+'Value'));
}
checkWinX();
checkWinO();
if (square0Value != "" && square1Value != "" && square2Value != "" && square3Value != "" && square4Value != "" && square5Value != "" && square6Value != "" && square7Value != "" && square8Value != ""){
checkBoardFull();
}
}
The issue lies in the clickX() and clickO() functions where I am trying to set the value of the (eval(squareId+'Value')) as the X or the O value that is needed. I want to make this as dynamic as possible so don't have to write a function for every modal.
Not sure why you are using eval.
$("#"+squareId).addClass()
may be enough
Here would be my suggestion.
var button = $(event.relatedTarget);
If I am reading this right, that is the button that was clicked that caused the modal to show. If that is the case, then I believe it is a far assumption that only one modal can show at a time. If that is true, then what you can do is make that variable scoped higher, not within that handler.
What does that do for you? Well, if you do that, then you can use that element within your clickX and clickY. For instance...
function clickX(){
button.data('xo', 'X');
button.find('.xo').html('X');
}
I'm unclear what the others are referencing, but if you have the button then you have access to finding it's nested children or looking for parent elements if you need to find them.
So yeah... rebuilding my global Square Values into an array was a MUCH easier way of organizing things... sorry everyone.
So I'm in a bootcamp, bout to begin the 7th week. We have an API assignment, and I chose to use the Giphy API. Okay, I've made the ajax call, have the json object, am displaying gifs with a button click. Once the gifs load, you should be able to make image animate, then upon next click, the image becomes still again. the process should be able to repeat itself ad nauseam. I have it set up the way that makes sense; however, I cant seem to get the urls to change upon click the way it's currently written. I tried .splice url, and using concat to complete updated url; however, I cant seem to figure out how to get the image to revert back to still state upon next click... been working on this for sooooo many hours, will someone please lend me a fresh set of eyes?
here's my js and jquery
// $("#loadTimer, .buttonGallery, #btnGeneratingbtn").hide();
var topics = ["Brandon", "Biggie Smalls", "Dr. Seuss", "Paul McCartney", "John Lennon", "Will Ferrell", "Jimmy Fallon", "Chris Farley", "Dane Cook", "Eminem", "Nas", "Jay-Z", "Rakim", "William Shakespeare","Jim Morrison", "James Maynard", "Serj Tankian"];
var gifcount = 0;
var gifLocation;
var clickCount = 0;
var buttonFactory = function() {
$(".buttonGallery").empty();
for (i = 0; i < topics.length; i++) {
var imAbutton = $("<button>");
imAbutton.addClass("yup");
imAbutton.attr("data-name", topics[i]);
imAbutton.text(topics[i]);
$(".buttonGallery").append(imAbutton);
}};
buttonFactory();
$("#anotherButton").on("click", function(event) {
event.preventDefault();
// This line grabs the input from the textbox
var onemorebutton = $("#user-input").val().trim();
// Adding movie from the textbox to our array
topics.push(onemorebutton);
// Calling renderButtons which handles the processing of our movie array
buttonFactory();
});
$(".yup").on("click", function(){
$("#gif-Gallery").empty();
var searchTermUpdate;
var searchTerm = $(this).attr("data-name");
// removing white space between two-word strings, replacing with a "+" \\
searchTermUpdate = searchTerm.replace(/ +/g, "+");
var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + searchTermUpdate + "&api_key=dc6zaTOxFJmzC&limit=10";
$.ajax({
url: queryURL,
method: 'GET'
}).done(function(response) {
console.log(response);
var results = response.data;
for (var i = 0; i < results.length; i++){
gifcount = gifLocation;
var gifDIV = $("<div class='unit' data-state='still'>");
var pRating = $("<p>").text("Rating: " + results[i].rating);
var gifImg = $("<img id='gifimg' class='col-md-4'>");
gifImg.attr("src", results[i].images.fixed_height_still.url);
gifImg.attr({'data-animate' : results[i].images.fixed_height.url});
gifImg.attr({'data-state' : "still"});
gifImg.attr({'data-still' : results[i].images.fixed_height_still.url});
gifDIV.append(pRating);
gifDIV.append(gifImg);
gifDIV.append(gifLocation);
gifcount++;
// appending gif div to DOM \\
if (results[i].rating !== "g" || "pg" || "pg-13" || "y"){
$("#gif-Gallery").append(gifDIV);
}}
$(".unit").on("click", function(){
var state = $(this).attr('data-state');
if (state === "still") {
$(this).attr("src", $(this).attr("data-animate"));
$(this).attr("data-state", "animate");
} else {
$(this).attr("src", $(this).attr("data-still"));
$(this).attr("data-state", "still");
}
// var imgPath = this.children[1].src;
clickCount++;
var a;
var b;
var c;
var d;
var f;
// if (clickCount % 2 === 0 ){
// for (i=0; i < imgPath.length; i++){
// // locating index of underscore, storing that value in var a\\
// var a = imgPath.indexOf("_");
// // removing all characters to the right of the underscore \\
// var b = imgPath.slice(0, a);
// f = b;
// // setting var c to a string value of .gif \\
// var c = ".gif";
// // combining var b and var c to complete updated image path \\
// var d = b.concat(c);
// }
// setting image url to animated url \\
// $(gifImg).attr("src", d);
// this.children[1].src = d;
});
});}); //
and here is the html if needed :
<body>
<div class="jumbotron">
<div class="container">
<div class="myHeader">
<h1>WordSmiths</h1>
<span class="text-muted" id="jtronText">
<div id="sometimeGone">Sometimes</div><div id="loadTimer">someone opens their mouth and you can't help but to be dazzled with the magic.</div>
</span>
<p class="text-success" id="instructionsOne">
Click a button, see what happens!
</p>
<p class="text-success" id="instructionsTwo">
Now you can create your own buttons!!!
</p>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="buttonGallery"></div>
<h4>Create buttons, find Gifs!: </h4>
<form id="btnGeneratingForm">
<label for="input">Anything: </label>
<input type="text" id="user-input">
<br>
<input type="submit" id="anotherButton" value="More buttons">
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div id="gif-Gallery"></div>
</div>
</div>
again, thanks in advance!
Robert
I am actually doing the same project! I did it a pretty a similar way. I think the issue may be that you're appending the animated src to the image holder div instead of the child image itself. This line:
$(this).attr("src", $(this).attr("data-animate"));
Is what is giving you trouble I think.
Best of luck with the project, I hope that helps.
I am building an app using Cordova and JQuery Mobile 1.4.3 which pulls data from a webservice. I have no problems attaining the data once cordova has loaded and updating the DOM.
The data is presented within a collapsible list with each heading and view updated according to the data returned from the webservice.
However, once the DOM update is complete, the collapsible heading does not refresh its style while the content does. Additionally the heading remains clickable too.
I have scoured the web for a solution but cannot find a way to get the headers for the collapsible to refresh their views.
I have tried using $("#id").collapsible('refresh') to no avail.
Any help on how to update the UI would be great
Code below.
Header scripts of index.html
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
init();
}
</script>
Snippet of Markup
<div data-role="page" id="home" data-title="Home">
<div data-role="header" data-id="foo" data-position="fixed">
<h1>Title</h1>
</div>
<div data-role="content" id="collapsible_set">
<h3 id="date"></h3>
<div data-role="collapsibleset" id="datacollapsible" data-inset="false">
<!-- First Collapsible -->
<div data-role="collapsible" id="test" class="content">
<h3 class="title"></h3>
<ul data-role="listview" data-inset="false">
<li style="font-size: 1.4em;">
<p class="description" style="overflow: visible; text-overflow: clip; white-space: normal"></p>
<p>Source:</p>
<p></p>
<div data-role="controlgroup">
Add to Favorites
Share
</div>
</li>
</ul>
</div>
<!-- More Collapsibles below -->
</div>
</div>
JS
var data;
var pattern = new RegExp('^http');
function init() {
initializeDataSet();
insertData();
$("#test").collapsible('refresh');
}
function insertData() {
// set date
var date = new Date();
var options = {
weekday: "long", year: "numeric", month: "long", day: "numeric"};
var outputDate = date.toLocaleString("en-us", options);
$("#date").html("" + outputDate);
// Get content elements and add data
var content = $('.content');
if (content) {
for (var i = 0; i < content.length; i++) {
var temp = content[i];
temp.getElementsByTagName('h3')[0].innerHTML = data[i]['title'];
if(data[i]['word']){
temp.getElementsByTagName('p')[0].innerHTML = data[i]['word'] + ": " + data[i]['description'];
} else {
temp.getElementsByTagName('p')[0].innerHTML = data[i]['description'];
}
if(pattern.test(data[i]['source'])) {
temp.getElementsByTagName('a')[0].setAttribute("href", data[i]['source']);
temp.getElementsByTagName('a')[0].setAttribute("target", "_blank");
} else {
temp.getElementsByTagName('a')[0].removeAttribute("href");
temp.getElementsByTagName('a')[0].removeAttribute("target");
}
temp.getElementsByTagName('a')[0].innerHTML = data[i]['source'];
}
}
}
/**
* initialise the dataset to a global variable when the app launches.
* #returns {undefined}
*/
function initializeDataSet() {
// make request to get data
var request = createRequest();
if (request === null) {
alert("Error, can't get data");
return;
}
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
data = JSON.parse(request.responseText);
}
}
};
var params = "date=" + createDate();
request.open("POST", "URL FROM WHERE I AM GETTING DATA", false);
//Send the proper header information along with the request
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(params);
}
function createDate() {
var date = new Date();
var day = date.getDate();
if (day < 10) {
day = "0" + day.toString();
}
var month = date.getMonth() + 1;
if (month < 10) {
month = "0" + month.toString();
}
return date.getFullYear() + "-" + month + "-" + day;
}
First off, you need to understand how jQM enhances its' widgets, e.g. collapsible. The initial HTML markup of a collapsible doesn't remain as is after the widget is created.
<div data-role="collapsible">
<h3>Header</h3>
<p>Contents</p>
</div>
The above HTML markup is converted into the following.
<div data-role="collapsible" class="ui-collapsible ui-collapsible-themed-content">
<!-- Header -->
<h3 class="ui-collapsible-heading">
<a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-btn-inherit ui-icon-minus">
Header
</a>
</h3>
<!-- Contents -->
<div class="ui-collapsible-content ui-body-inherit" aria-hidden="false">
<p>Contents</p>
</div>
</div>
You're not updating collapsible's header/content properly, you need to target inner elements. Below is an example.
Edit: I forgot to mention that you don't need to call refresh method since you aren't replacing any part of the collapsible.
var data = [{
"title": "foo1",
"content": "foo1 content"
}, {
"title": "foo2",
"content": "foo2 content"
}];
$.each(data, function (i, value) {
$("#datacollapsible .ui-collapsible:eq(" + i + ")")
.find("h3 a")
.text(value.title)
.end()
.find(".ui-collapsible-content p")
.text(value.content);
});
Demo