Hello I have made this js code to change the view from List to Grid and the opposite as well but I want to keep the current view state after refreshing the page, I have seen many videos talking about cookie and localStorage but I don't know how to use them since I am still beginner in programming could you tell me how to do ?
script.js:
let x = document.getElementById('x');
let z = document.getElementById('z');
x.addEventListener('click', function() {
let className = z.className;
if (className == 'list') {
z.className = 'grid';
}else{
z.className = 'list';
}
});
index.php:
<i class="" id="x"></i>
<div class="list" id="z">
.
centent
.
</div>
You can:
load the stored class from localStorage
see whether it's valid and different from the current class
store its current value upon each click
let x = document.getElementById('x');
let z = document.getElementById('z');
let cl = localStorage.getItem("class");
if (cl !== z.className) z.className = cl;
x.addEventListener('click', function() {
let className = z.className;
if (className == 'list') {
z.className = 'grid';
}else{
z.className = 'list';
}
localStorage.setItem("class", z.className);
});
Since stackoverflow.com considers direct operation with localStorage to be unsafe, I had to create a Fiddle for proof-of-concept. See here: https://jsfiddle.net/q68vnctL/
You can test by running it, clicking the "Click Me!" button as many times as you like, click on "Run" again and see that the color remains whatever it was.
localstorage is used as key-value pairs, both being always strings.
you can use localStorage.setItem('view-setting', 'list').
this will create a localstorage variable named view-setting and will define its value as list. You can fetch the data using localStorage.getItem('view-setting'). Similarly items can be deleted using localStorage.removeItem('view-setting').
So after setting the view in localStorage, you can fetch it and on reload check its last stage and add conditionals in HTTP accordingly.
You can get further help from:
Loading JS LocalStorage into PHP Variable
or
https://www.w3schools.com/html/html5_webstorage.asp
Related
I have a problem with overlapping HTML id. The reason for this problem is that more than 100 screens are opened and used one at a time, and then they are turned into multi-tabs in an active state.
I was instructed not to modify the existing code as much as possible while implementing multi-tab. Many screens are similar, so many are copied and used. Therefore, there is a case where the HTML id, which is the problem I mentioned, is duplicated.
How can I implement multi-tap with no conflicts of id without modifying existing sources as much as possible?
I thought of a way. Copy the screen and put it in the data, and then create the screen again.
The problem is that I use js-based Web Grid, but when I call the screen again, the screen is not visible. I think it's not a web grid problem. The button function that gives an alert when clicked initially works, but it did not work when it was reloaded.
HTML (Frame)
<div id="flex_navi_btn_area"></div>
<div id="menuContent"></div>
Script (Jquery Use)
function menuCall(url, inner_url_yn, obj){
let $navBtnWrap = $('.navButton.tab-content-'+obj.key);
if ($navBtnWrap.length > 0) {
$navBtnWrap.eq(0).click();
return;
} // Tab already exists
let currentKey = $('#menuContent').data('key');
if(currentKey != null && typeof currentKey != "undefined") {
$('#flex_navi_btn_area').data('content-'+currentKey, $('#menuContent').clone());
} // Save screen is use
var params = '';
ajaxCall(url, params, function(data){
$('#menuContent').empty();
$('#menuContent').append(data);
$('#menuContent').data('key', obj.key);
addTab(url, obj);
});
}
function addTab(url, obj) {
$('#flex_navi_btn_area .navButton').removeClass('on'); // For css
$('#flex_navi_btn_area').append(`<div onclick="selectTab($(this))" data-key="`+obj.key+`" class="navButton on tab-content-`+obj.key+`">`+obj.title+`</div>`); // Tab html
}
function selectTab($selectedTab) {
let currentKey = $('#menuContent').data('key');
let nextKey = $selectedTab.data('key');
if(currentKey != null && typeof currentKey != "undefined") {
$('#flex_navi_btn_area').data('content-'+currentKey, $('#menuContent').clone());
} // Save screen in use
if(currentKey == nextKey) return; // New and existing screen is same
$('#menuContent').empty();
let $content = $('#flex_navi_btn_area').data('content-'+nextKey);
if ($content != null && typeof $content != "undefined") {
$content.replaceAll($('#menuContent'));
$content.data('key', nextKey);
} // Change screen
$('#flex_navi_btn_area .navButton').removeClass('on'); // For css
$selectedTab.addClass('on'); // For css
}
HTML (content)
<div onclick="alert('html')"><div>
<div id="btn"></div>
<script>
$('#btn').click( () => { alert('js'); });
</script>
First load, working well
Second or more load, only 'html' alert working
I know that when there is the same html id, it is indistinguishable. So what I want is to isolate the screen that's currently being shown so that it can't be searched, and then bring up the screen that's been isolated and show it on the screen.
I would suggest you try something like this
My other suggestions would be, that you get make two separate arrays. One for all the buttons with a duplicate ids and one array for all the tabs with duplicate ids.
Then use a basic for loop (let i = 0; i < duplicate_btns.length; i++) find matching pairs and add i (number) to the end of the id.
Hope this helps
I have this situation with my Wordpress site where products with variations are hitting the DOM while missing some inner text on a certain element (which is the same behavior as a product without a sku), but when I console.log the element, the text is there. Here is the code:
const makerBtn = document.getElementById("maker-button");
const sku = document.getElementsByClassName("sku");
const newLink = document.createElement("a");
newLink.innerText = "Buy at Maker's Site";
newLink.className += "fusion-button button-flat fusion-button-default-size button-custom button-3 fusion-button-default-span fusion-button-default-type";
newLink.addEventListener("click", ()=> {
newLink.target = "_blank";
newLink.href = sku[0].innerHTML.toString();
});
makerBtn.appendChild(newLink);
I've added url's to some products in the sku and if they are there, then you click the button and you will be taken to a new site. I've just been trying to find a way to hide the button if it doesn't have a sku, but if I add code like this:
if (sku[0].innerHTML === "") {
newLink.style.display = "none";
}
It will work except the button is hidden for products that have variations too (they have a dropdown menu and you can choose between different colors, etc.) because the sku[0].innerHTML is hitting the DOM as an empty string even though I console log it and the url is there.
I can't figure out which property of these variable products I can add to a conditional so that these pages behave differently. Thank you for any help.
Maybe you can try:
if (sku[0].innerHTML === "") {
newLink.style.opacity= "0.0";
}
For some reason, my website still showing images that were already deleted from the specified folder and I have no idea why that's happening and how to solve that.
Process: When the button to delete all admins is pressed, it calls a PHP function that truncate the tables administration, adminimg and login, delete all images from a folder related to id's on table administration with unlink(), and create a registry on administration table with id=1(auto_increment) and name="abc".
Problem: I have a jQuery function that display a specific admin information on textboxes, verify the value in the textbox for the adminID, and display the image associated to that id. After executing the process above, when i call the jQuery function, it display correctly the id=1 and name="abc" but shows the deleted image associated to the admin with id=1 before truncate the tables.
jQuery function (if necessary)
$(".btneditadmin").click( e =>{
let textvalues = displayDataAdmin(e);
let id = $("input[name*='idadmin']");
let name = $("input[name*='nameadmin']");
id.val(textvalues[0]);
nome.val(textvalues[1]);
var img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
$("#admin-image").attr('src',img_url);
});
function displayDataAdmin(e) {
let id = 0;
const td = $("#tbody tr td");
let textvalues = [];
for (const value of td){
if(value.dataset.id == e.target.dataset.id){
textvalues[id++] = value.textContent;
}
}
return textvalues;
}
If you're sure that image isn't there anymore then it's caching issue and something like this would take care of it
let img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
img_url += '?' + new Date().getTime() ; // cache killer
$("#admin-image").attr('src', img_url);
However, you're calling that function no matter what so I would suggest a onload/error check
$('#admin-image').load(function(){ // when loaded successfully
console.log('success');
}).error(function(){ // when theres an error
$(this).remove()
// or you could replace it with a default image
$(this).attr('src', '/images/default.jpg');
});
I am making a javascript note-taking app. Here is the code so far:
Javascript is:
var inputValue = document.getElementById('myInput');
var input = document.getElementById('myInput');
var button = document.getElementById('myButton');
function run(){
localStorage.setItem('inputer', inputValue);
let p = document.createElement('p');
p.id = 'content';
p.innerHTML = inputValue.value;
document.body.appendChild(p);
}
window.addEventListener('load', () => {
var savedUserData = localStorage.getItem('inputer');
var p2 = document.createElement('p');
p2.innerHTML = savedUserData.value;
document.body.appendChild(p2)
});
And the HTML is:
<input id = "myInput">
<button id = "myButton" onclick = "run();">
Take note:
</button>
It works by stacking notes on top of notes and saving the data in local storage. But for some reason, it does not save the notes correctly. It will stack them but not save them. Also, it says this: "undefined". I would assume that that is because it checks the value of the input first before anything has been in it. And as I am writing this I am thinking that my idea is not going to work because there is mutiple input. So how would I fix this so this so the user can stack notes ontop of notes, and they will all be stored in local storage and come back to the user when the page reloads? Thank you and have a good day!
It seems your first line of code should say:
var inputValue = document.getElementById('myInput').value;
I am trying to generate a view based on the current user's group name. Group Name I am gathering from the custom list.
My question is how to apply the gathered group name to 'Group Name' column as a view parameter.
The only solution I figured:
I have created a view with a parameter.
I have added an HTML Form Web Part into the same page and connected it to the list view (sending the value to the parameter via web part connection). Then with a window.onload function I gather the current user's group name and pass this value via Form Postback function. But since the Postback function triggers full page reload, it falls into the endless loop of form submission > page reload.
Another way I have tried is attaching a click event listener to the BY MY GROUPS tab and it works perfectly, but the only disadvantage is that the page reloads each time user clicks on this tab, which I would like to avoid.
So the solution that I need is a way to post the form without a page reload.
Another option suggested here is to use CSR (client side rendering), but that has its own problems:
This code does not work as it is supposed to. In the console it shows me correct items, but the view appears untouchable.
Even if it worked, the other column values are still viewable in the column filter, as in this screenshot:
So, it seems that CSR just hides items from the view (and they are still available). In other words its behavior is different from, for example, a CAML query.
Or am I getting it wrong and there's something wrong with my code?
Below you can find my CSR code:
<script type='text/javascript'>
(function() {
function listPreRender(renderCtx) {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
var currUserID = _spPageContextInfo.userId;
var cx = new SP.ClientContext('/sites/support');
var list = cx.get_web().get_lists().getByTitle('Group Members');
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
cx.load(items, 'Include(_x006e_x50,DepID)');
cx.executeQueryAsync(
function() {
var i = items.get_count();
while (i--) {
var item = items.getItemAtIndex(i);
var userID = item.get_item('_x006e_x50').get_lookupId();
var group = item.get_item('DepID').get_lookupValue();
if (currUserID === userID) {
var rows = renderCtx.ListData.Row;
var customView = [];
var i = rows.length;
while (i--) {
var show = rows[i]['Group_x0020_Name'] === group;
if (show) {
customView.push(rows[i]);
}
}
renderCtx.ListData.Row = customView;
renderCtx.ListData.LastRow = customView.length;
console.log(JSON.stringify(renderCtx.ListData.Row));
break;
}
}
},
function() {
alert('Something went wrong. Please contact developer')
}
);
});
}
function registerListRenderer() {
var context = {};
context.Templates = {};
context.OnPreRender = listPreRender;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(context);
}
ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');
})();
</script>