My JS work only if i reload page.
Description my problems
1.I have book
2.Book have description
3.In action show i have logic for present description
Logic:
1. If description.length > 250 i show 250 symbols and show view_more button
2. If user click on button then my js must work
4.When i on books#index => choose some book(#show)=> now i on book_page and i see view_button => when i click => nothing was happen
5. But if i reload page before click on button => my js work fine
My js
(function(window, document, undefined){
window.onload = init;
function init(){
let btn_view_more = document.getElementById('button_for_view_more')
let description_all = document.getElementById('book_description_all')
let description_short = document.getElementById('book_description_short')
btn_view_more.addEventListener('click', ()=>{
description_all.classList.remove('hide_description')
description_short.style.display = 'none'
});
};
})(window, document, undefined);
But i have new version of my js
document.addEventListener("turbolinks:load", function() {
myFunc();
})
function myFunc(){
let btn_view_more = document.getElementById('button_for_view_more')
let description_all = document.getElementById('book_description_all')
let description_short = document.getElementById('book_description_short')
btn_view_more.addEventListener('click', ()=>{
description_all.classList.remove('hide_description')
description_short.style.display = 'none'
});
}
New version work fine even i don't reload page, but i have error in my console
Cannot read properties of null (reading 'addEventListener') (can't find id button_for_view_more)
What i want:
1. Js work even i don't reload page
2. Zero error in console
My solution is connect js only to the page where it is used, delete from javascript/some.js and drop require from pack/application.js. You can also add a condition to your script that will check whether such an ID is currently on the page. And only after run the main block.
Related
I want to be able to have the option persist after I added a tag. A similar question was solved here:
Dynamically add item to jQuery Select2 control that uses AJAX
But a commenter is right, it is only solved with an additional input box somewhere not in the original select box.
[![Question kinda solved][1]][1]
I tried a number of things and they all do not work:
returning an object with createOption or createSearchChoice
Appending a new Option
This is because the widget already secretly adds a new options as is necessary to accommodate the new tag, but if it wasn't a tag from the original data, it will delete it if a new option is selected. I thought maybe on the select2:select event, I could see if the new value is in the data somewhere. Alas, that data is hard to find.
[1]: https://i.stack.imgur.com/CyCC4.png
Here are some failed attempts with commentary
var quote = {};
google.script.run.withSuccessHandler(function(e){
quote = $('#quote').select2({
width:'100%',
data: e, //[{id:'quote', text:'quote'},{id:'quote2', text:'quote2'}]
tags: true,
/*Alas, this doesn't work either becuse the tag is still in the option when we check fo rit
createTag: function(){
if (quote.find("option[value='" + params.term + "']").length) quote.append(Option(params.term,params,term,true,true)).trigger('change')
return {id: params.term, text:params.term})
*/
//insertTag: function(d,t){d.push(t)} Didn't work either
allowClear:true,
placeholder:'No Quote'
}).on('select2:select',function(e){
/*
// Set the value, creating a new option if necessary
This doesn't work because the new item is in the option thingy temporarily while we're trying to see if its there
if (quote.find("option[value='" + e.params.data.id + "']").length) {
quote.val(e.params.data.id).trigger('change');
} else {
// Create a DOM Option and pre-select by default
var newOption = new Option(e.params.data.id, e.params.data.id, true, true);
// Append it to the select
quote.append(newOption).trigger('change');
}
*/
if (e.params.data.id&&(quotes.indexOf(e.params.data.id)!=-1)){
loadQuote(e.params.data.id)
} else {
//new quote so now we have to make preparations...
quotes.push(e.params.data.id)
console.log(e.params.data)
console.log(quotes)
var newOption = new Option(e.params.data.id,e.params.data.id,true,true)
quote.append(newOption).trigger('change')
//don't send anything to the server, because there is no need
}
})
quote.val(null).trigger('change')
So I'm learning dart and web development in general. Right now I'm experimenting with the history API. I have:
import 'dart:html';
void main() {
ParagraphElement paragraph = querySelector('.parag');
ButtonElement buttonOne = querySelector('.testaja');
buttonOne.onClick.listen((_) {
window.history.pushState(null, 'test title', '/testdata/');
window.history.forward();
});
ButtonElement buttonTwo = querySelector('.testlagi');
buttonTwo.onClick.listen((_) {
window.history.back();
});
window.onPopState.listen((_) {
window.alert(window.location.pathname);
});
}
My conclusion is that onPopState only triggers when we click on browser's back or forward button, or using window.history.forward() or window.history.back(). So this is like, we render a template, then change its url using pushState, not update template based on url changes. Is this true or not?
Edit:
So maybe I'm not clear enough. Let's say I have something like this:
void main() {
InputElement input = querySelector('.input')
ButtonElement changeUrl = querySelector('.change-url');
changeUrl.onClick.listen((event) {
window.history.pushState(null, 'test tile', input.value);
});
Map urls = {
'/' : showRoot,
'/user/:id' : showUserProfile
};
window.onPopState.listen((_) {
var location = window.location.pathname;
urls[location]();
});
}
I can get input's value by clicking on changeUrl, and then by adding a listener to changeUrl, I can use pushState to update url on browser. What I'm expecting is, when I do pushState, the window.onPopState will triggered and invoke the callback when in reality it doesn't.
tldr, what I'm trying to achieve is:
listen on url changes -> get current url -> use current url to invoke a handler stored in a map. Using onHashChange also doesn't work when updating url using pushState prefixed by #.
edit
set the hash using
window.location.hash = input.value;
this triggers the PopState and HashChange event
as does a click on such a link
abc
original
I don't have time to take a close look what you'r trying to achive..
But I think you should add an event handler for 'window.onHashChange' this way ordinary links work too for navigation, not only buttons with onclick-handlers modifying browser history.
I work on a Windows 8 app, and from a page that I use link hystory for running back and forward through the app, I also have 3 or 4 links to external websites(eg: facebook or my site). I tried to run them in iframe, or also to make them open in the default browser like simple links. Both method resulted in an error in base.js that says it can't handle my error (!?) I searched a lot before asking here. I watched msdn sample that works just fine, but if i copy what I need in my app results in the same error. I I use it from another page where I dont have forward history, it works, but i really need it on the front page. Any ideeas? Thank you very much.
LE:
This is my items.js code: ( for the items.html page )
(function () {
"use strict";
var appViewState = Windows.UI.ViewManagement.ApplicationViewState;
var ui = WinJS.UI;
ui.Pages.define("/pages/items/items.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
var listView = element.querySelector(".itemslist").winControl;
listView.itemDataSource = Data.groups.dataSource;
listView.itemTemplate = element.querySelector(".itemtemplate");
listView.oniteminvoked = this._itemInvoked.bind(this);
this._initializeLayout(listView, Windows.UI.ViewManagement.ApplicationView.value);
listView.element.focus();
WinJS.Utilities.query("a").listen("click", this.linkClickEventHandler, false);
},
// This function updates the page layout in response to viewState changes.
updateLayout: function (element, viewState, lastViewState) {
/// <param name="element" domElement="true" />
var listView = element.querySelector(".itemslist").winControl;
if (lastViewState !== viewState) {
if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
var handler = function (e) {
listView.removeEventListener("contentanimating", handler, false);
e.preventDefault();
}
listView.addEventListener("contentanimating", handler, false);
var firstVisible = listView.indexOfFirstVisible;
this._initializeLayout(listView, viewState);
if (firstVisible >= 0 && listView.itemDataSource.list.length > 0) {
listView.indexOfFirstVisible = firstVisible;
}
}
}
},
linkClickEventHandler: function (eventInfo) {
eventInfo.preventDefault();
var link = eventInfo.target;
WinJS.Navigation.navigate(link.href);
},
// This function updates the ListView with new layouts
_initializeLayout: function (listView, viewState) {
/// <param name="listView" value="WinJS.UI.ListView.prototype" />
if (viewState === appViewState.snapped) {
listView.layout = new ui.ListLayout();
} else {
listView.layout = new ui.GridLayout();
}
},
_itemInvoked: function (args) {
var groupKey = Data.groups.getAt(args.detail.itemIndex).key;
WinJS.Navigation.navigate("/pages/split/split.html", { groupKey: groupKey });
}
});
})();
And from items.html I have different types of links: some of them links to other application pages, from where I can return with history buttons back/forward and some of them are links to external page. Simple link.These links crashes my app with the error that I mentioned below. If I erase the next line:
WinJS.Utilities.query("a").listen("click", this.linkClickEventHandler, false);
from my js script, external links works, but I dont have anymore history buttons in my others's app pages.
You are trying to use the navigation framework to navigate to an external URI. It's usually meant to be used within the application's local context and pages that can contain 'fragments' to load up into your main nav control.
I wouldn't hook anchor tags with your function call, instead in your linkClickEventHandler I would do the following to only hook your internal links
WinJS.Utilities.query(".nav").listen("click", linkClickEventHandler, false);
in turn your internal links would be
click me
This approach only hooks the navigation framework into your internal links. Another approach is to inspect the 'this.href' in your handler and if it contains http:// or https:// then call window.open instead
I'm developing an application in Rails wich acts as a network and apps monitor. I'm using Active Admin Dashboard as a main page, showing the status of every server and some apps in my network. I'd like to configure the dashboard page to autorefresh every x minutes, but I don't know where to configure this setting, because I don't have full control of the html rendered by the dashboard. Have anyone managed to do it?
Thanks
In config/initializers/active_admin.rb you can register javascripts:
config.register_javascript "/javascripts/admin-auto-refresh.js"
Then create a admin-auto-refresh.js that does exactly that.
You'll also want to register admin-auto-refresh.js in your config/environments/production.rb
config.assets.precompile += "admin-auto-refresh.js"
UPDATE:
Added some code to refresh the page after 5 seconds. Add this to /javascripts/admin-auto-refresh.js
$(function() {
setTimeout(location.reload(true), 5000);
})
Here's the final code, thanks very much to #JesseWolgamott.
$(function() {
var sPath = window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
if (sPage == 'admin'){
setTimeout("location.reload(true);", 10000);
}
})
Below is code that will refresh without the page flashing. It is enabled by having at least one element in the page with a class tag of needs_updating. Include this code snippet in any javascript that is loaded and then add the tag any where on the page.
The only downside is this ONLY updates the html body of the page.
For example
show do |my_model|
...
if my_model.processing?
row :status, class: 'needs_updating' do
'we are working on it...'
end
else
row :status do
'ready'
end
end
....
end
so if the model is still processing then you get the class tag 'needs_updating' which will cause the below javascript to be invoked every 10 seconds
jQuery(document).ready(function($) {
if ($('.needs_updating').length > 0) {
console.log("we need some updating soon");
var timer = setTimeout(function () {
console.log("re-loading now");
$.ajax({
url: "",
context: document.body,
success: function(s,x) {
$(this).html(s);
if ($('.needs_updating').length == 0) {
clearInterval(timer);
}
}
});
}, 10000)
}
})
seems to me that I didn't fully understand the concept behind jquerymobile, because I have no idea how to solve this issue.
What I want to do is load some HTML Content via AJAX, according to location.hash, put it into a new page and load this page.
But if I create a page myself by using the pagebeforechange event, jquerymobile just ignores it, creates its own div and my content won't be displayed.
How do I have to do it?
Edit:
This is how I am currently doing it, but it wont't work.
$(function() {
getPageContent(top.location.href, false);
$(document).bind( "pagebeforechange", function( e, data ) {
getPageContent(data.toPage, true);
});
});
function getPageContent(pageUrl, changedPage) {
var re = /.*\/#(.*)/;
var result;
result = re.exec(pageUrl);
window.page = result[1].substr(0,3);
window.id = result[1].substr(3);
window.ajaxUrl = "request.php?page="+window.page+"&id="+window.id;
$.ajax({
url: window.ajaxUrl,
success: function(data) {
if(data.error) {
alert(data.error);
}
else if(data.data) {
if(changedPage) {
changePage(data.data));
}
else {
$('#content[role="main"]').html(atob(data.data));
setupPage();
}
}
else {
alert("UNKNOWN ERROR: "+data);
}
}
});
}
function changePage(html) {
var div = "<div></div>";
var newPage = $(div).attr("data-role", "page").attr("data-url", window.page+window.id);
var header = $(div).attr("data-role", "header");
var content = $(div).attr("data-role", "content");
var footer = $(div).attr("data-role", "footer");
$("body").append(newPage);
newPage.append(header, content, footer);
content.html(html);
newPage.page();
}
Complete edit of the whole answer:
First. Set your body id to id=body. Then when you want to load the new page and change to it, use an ajax call like this:
$.get(window.ajaxUrl, function(data){
$('#body').append("<div id='newPage' data-role='page'></div>"); //Creates a new page.
$('#newPage').html(data); //Loads the html content into the new page.
$.mobile.changePage('#newPage'); //Navigates to the new page.
}
This sends an ajax call with the method GET to the url found in your window.ajaxUrl. If the call is successful, it creates a new page named "newPage", and fills it with the data received from the ajax call. Then redirects to the newly created page.
This jsFiddle shows the basics of how it works. However, it doesn't use any ajax call.
You have to refresh the page with jQueryMobile :
$("#your-page").trigger("create");
--Edit
<script>
$("#thepage").live("pageshow", function(){
$("#thepage).trigger("create");
});
</script>
Change the content of #thepage before 'pageshow' event
It does this for you automatically - just make a regular link to the page and jquery mobile will shwo the loading spinner, load it in the background via ajax, then transition to the new page.
Make sure all your pages are decide with unique IDs and data-role='page'. Check out the start guide here:
http://jquerymobile.com/demos/1.1.0/docs/about/getting-started.html