how i can keep modal open after click? - javascript

My question is different and didn't get any solution.Question is when i click on active modal opens for 1 sec and then page refresh and change status active to inactive.
I want to keep modal open when i click on active then after hitting send from modal page reloads and change status to inactive.
My Modal:
<div class="modal fade text-left" id="small" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel19"
aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<form method="post">
<input type="hidden" name="_token" value="{{csrf_token()}}">
<div class="modal-header">
<h4 class="modal-title" id="heading-name">Reason</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="receiver" for="to">To: </label>
</div>
<div class="form-group">
<textarea type="text" class="form-control" name="message" id="message"></textarea>
</div>
</div>
<input type="hidden" name="message_value" id="message_value">
<div class="modal-footer">
<button type="button" class="btn grey btn-outline-secondary" data-dismiss="modal">
Close
</button>
<button type="submit" class="btn btn-outline-primary" data-target="myModalLabel19"
data-toggle="modal">Send
</button>
</div>
</form>
</div>
</div>
</div>
For Loop:
for (var i = 0; i < response.data.length; i++) {
if (response.data[i]['status'] == 1) {
operatorStatus = "Active";
statusColor = "<button class='btn btn-primary' onclick='fn_statusUpdate("+response.data[i]['id']+",0);reason("+response.data[i]['id']+")'>Active</button>";
} else {
operatorStatus = "Active";
statusColor = "<button class='btn btn-danger' onclick='fn_statusUpdate("+response.data[i]['id']+",1)'>Inactive</button>";
}
}
Function:
function reason(id) {
$('.receiver').text('To: ' + id);
$('#message_value').val(id);
console.log((JSON.stringify(id)));
$('#small').modal('show');
}

Pseudo Code
Okay, rather than re-writing the code for you, I'm just gonna write some pseudo code for you, simply because I'm not sure about how it all works or how it all ties together, etc...
So, you want to be able to do some stuff and remember the values prior to the page being refreshed, as far as I'm aware. So, I'd do something like this...
On load
...
if (sessionStorage.getItem('key') != null) {
// Show modal or set state to active or whatever...
} else {
// Hide modal and set state to inactive or whatever...
}
On State Change
....
if (state.active) {
// Do something...
} else {
// Do something else...
}
Explanation
I think you get where I'm going with this? If not it's really quite simple, if you have some value stored in session storage, then you can set the state to active and show the modal. I mean I think that's what you're trying to achieve?
Otherwise, just hide it all and set the state to inactive. I mean if you have many modals, then you could store an object into session storage using something like the code I've written below(keep in mind I've not tested this code):
const Session = {
get: key => {
try {
JSON.parse(sessionStorage.getItem(key));
} catch (e) {
return sessionStorage.getItem(key);
}
},
set: (key, data) => {
try {
sessionStorage.setItem(key, JSON.stringify(data));
} catch (e) {
sessionStorage.setItem(key, data);
}
}
};
So with this, you could just set some object, i.e. modalStates in you JavaScript, and then execute some check on load to check the state of each modal? I mean I'm not sure if you'd want to only allow only one modal to be active at any given time or if you'd want multiple to be active and open, etc...
Edit
Here's a simple demo, it won't work on here if I'm not mistaken, but if you try it on JSFiddle, I believe it should work without a problem. Again, this is just an example, it's merely here to give you an idea of how to solve your problem.
const dhtml = document.getElementById("demo");
const modal = document.getElementById("mdoal");
const btn = document.getElementById("change");
let state = {};
// Simple on error function.
const log = arg => {
console.clear();
console.log(arg);
};
// Simple get state function.
const getState = () => {
try {
if (JSON.parse(sessionStorage.getItem("demo")) != null) {
state = JSON.parse(sessionStorage.getItem("demo"));
} else {
state = {};
}
} catch (e) {
//log(e);
}
return state;
};
// Simple set state function.
const setState = () => {
try {
state = sessionStorage.setItem("demo", JSON.stringify(state));
} catch (e) {
//log(e);
}
};
// A simple on state change function.
const updateState = () => {
if (state.active == null) {
state.active = true;
} else {
state.active = !state.active;
}
setState();
log('State changed.');
};
// A simple render function.
const render = () => {
if (state.active == null || state.active == false) {
dhtml.textContent = 'Inactive';
modal.style.display = 'none';
} else {
dhtml.textContent = 'Active';
modal.style.display = 'block';
}
};
// A simple click handler for the change button.
const clickHandler = () => {
updateState();
getState();
render();
// window.location.reload(); // Simulate a http refresh/redirect.
};
// A simple on load function.
const onLoad = () => {
getState(); // Update the state object.
render(); // Initial render;
btn.onclick = clickHandler;
};
onLoad();
<div id="demo">
<p>Inactive</p>
</div>
<div id="mdoal" style="display: none">
<p>Hello World!</p>
</div>
<button id="change">state change</button>

You can use localStorage to achieve this basically, you don't have full code so I m assuming and and giving you an example:
function reason(id) {
$('.receiver').text('To: ' + id);
$('#message_value').val(id);
console.log((JSON.stringify(id)));
localStorage.setItem('isModalActive', '1'); // Add is modal active
$('#small').modal('show');
}
So now you set isModalActive 1 to users localStorage than you can check onload
$( document ).ready(function() {
if(localStorage.getItem('isModalActive') == '1'){
$('#small').modal('show');
}
});
Than when you closing to modal dont forget to change the value to 0
localStorage.setItem('isModalActive', '0'); // Add is modal not Active
Hope it helps.

Related

why doesn't my local storage works but, copy of same code works

i got two copies of the same code with slight variation but seems the second one isnt working.
I have tried using ChatGPT to identify issues however, nothing was found. But as far as i can see, it should work.
But, everything i refresh, its removed.
I want the buttons to stay there.
working code:
const todoList = document.querySelector(".todo-list");
const todoForm = document.querySelector(".add-todo");
const removeList = document.querySelector(".remove-List");
let items = JSON.parse(localStorage.getItem("todoList")) || [
{
title: "Write on, 'do not forget to', and press '+' to add",
done: false,
},
{
title: "press 'X' to remove",
done: false,
},
{
title: "search via 'search box'",
done: false,
},
{
title: "filter via 'all'",
done: false,
},
];
function addTodo(e) {
e.preventDefault();
const title = this.querySelector("[name=item]").value;
const todo = {
title,
done: false,
};
items.push(todo);
saveTodos();
this.reset();
}
function createList(list = [], listTarget) {
listTarget.innerHTML = list
.map((item, i) => {
return `<li>
<input type="checkbox" id="todo${i}" data-index="${i}"
${item.done ? "checked" : ""} />
<label for="todo${i}">${item.title}
<span class="font-size:30px" data-index="${i}">X</span>
</label>
</li>`;
})
.join("");
}
function toggleDone(e) {
if (!e.target.matches("input")) return;
const el = e.target;
const index = el.dataset.index;
items[index].done = !items[index].done;
saveTodos();
}
function removeSingle(e) {
if (!e.target.matches("span")) return;
const el = e.target;
const index = el.dataset.index;
items.splice(index, 1);
saveTodos();
if (items.length === 0) {
removeList.classList.add("hidden");
}
}
function saveTodos() {
localStorage.setItem("todoList", JSON.stringify(items));
createList(items, todoList);
showRemoveButton();
}
function removeData() {
items = [];
localStorage.removeItem("todoList");
createList(items, todoList);
removeList.classList.add("hidden");
}
function showRemoveButton() {
if (items.length > 1) return;
removeList.classList.remove("hidden");
}
todoList.addEventListener("click", toggleDone);
todoList.addEventListener("click", removeSingle);
todoForm.addEventListener("submit", addTodo);
removeList.addEventListener("click", removeData);
// Init list
createList(items, todoList);
<div class="ToDo-container">
<header class="app-header">
<div class="app-header1">
<div class="title">
<h1 class="app-title">ToDo List</h1>
</div>
<div class="select-button">
<select id="filter">
<option value="all">All</option>
<option value="completed">Completed</option>
<option value="incomplete">Incomplete</option>
</select>
</div>
</div>
<div class="search-header">
<input type="text" id="search" placeholder="Search Todos">
<button type="button" id="search-button" class="btn">Search</button>
</div>
</header>
<section class="app-body">
<div id="toDo">
<ul class="todo-list"></ul>
<form class="add-todo">
<input
type="text"
placeholder="Don't Forget to..."
name="item"
required
/>
<input type="submit" value="+" />
</form>
</div>
<button class="remove-List btn">Remove All</button>
</section>
</div>
// Add button function
function addButton() {
// Prompt for button link and name
var link = prompt("Enter the button link:");
var name = prompt("Enter the button name:");
// Create new button element
var newButton = document.createElement("button");
newButton.innerHTML = name;
newButton.setAttribute("onclick", "location.href='" + link + "'");
// Append new button to button container
document.getElementById("button-container").appendChild(newButton);
// Save buttons to local storage
saveButtons();
}
// Remove buttons function
function removeButtons() {
// Clear button container
document.getElementById("button-container").innerHTML = "";
// Save buttons to local storage
saveButtons();
}
// Save buttons to local storage
function saveButtons() {
// Get button container HTML
var buttonHTML = document.getElementById("button-container").innerHTML;
// Save button HTML to local storage
localStorage.setItem("buttons", buttonHTML);
}
// Load buttons from local storage on page load
window.onload = function () {
// Get button HTML from local storage
var buttonHTML = localStorage.getItem("buttons");
// Set button container HTML
document.getElementById("button-container").innerHTML = buttonHTML;
};
<div class="shortcuts-container">
<header class="shortcut-header">
<h1 class="shortcut-title">Quick Links</h1>
</header>
<section class="shortcut-body">
<form id="button-form">
<div id="button-container"></div>
<button type="button" onclick="addButton()">Add Button</button>
<button type="button" onclick="removeButtons()">Remove Buttons</button>
</form>
</section>
</div>
i want some help with identifying the bug in my code
As you have mentioned that your "second one" is not working, I have focused on the second piece of code. This peice of code adds a button for which we need to provide a link and name via alert box, which is technically supposed to be a hyperlink. I have added 2 buttons using that and refreshed page multiple times but the newly added buttons always stay. Local storage is working just fine.
Also, looking at your code, there is NO localStorage.removeItem() present. Hence the window.onload works fine. However, if you have any error logs in console of dev tools, please provide them for further debugging.
Also, if there is a way for you attach a video link of testing with dev tools console visible that would really help to understand why it doesn't work for you.

How to send data from modal dialog to sidebar (and vice versa) when event occurs (button clicked)?

I have a sidebar with a simple form with a dropdown that selects some categories of the entries. There's a button beside it for the user to add a new category. This button shows a modal dialog and in this dialog there's an input box for the user to input the new category name and an "Add New" button that will send the new item back to the sidebar. I would like for the respective dropdown to have the new category included among its options plus its text to be already populated with the new name.
All I could think so far was to use the localStorage but I then I don't know how to trigger updates to the dropdown on the sidebar (or any other element) when the button is pressed and the dialog is closed with a new value submitted. I've been looking at this and this but I couldn't really get it to work to my case.
I have supressed the Code.gs pieces because they work just fine and are not relevant.
sidebar.html
<script>
document.getElementById("btn-add-category").addEventListener("click", goToAddNewItem);
function goToAddNewItem(){
google.script.run.loadNewItemForm();
}
(async () => {
//After modal dialog has finished, receiver will be resolved
let receiver = new Promise((res, rej) => {
window.modalDone = res;
});
var message = await receiver;
document.getElementById("category-sidebar").value = message
})();
</script>
modal.html
This is the html file of the modal dialog:
<body>
<div class="form-group" id="input-category">
<label for="category">Category:</label>
<div class="input-group input-line">
<input type="text" class="form-control form-control-sm" id="category">
</div>
</div>
<div class="form-group">
<button id="btn-add-new" class="btn btn-dark btn-sm">Add New</button>
</div>
<script>
function findSideBar(limit) {
let f = window.top.frames;
for (let i = 0; i < limit; ++i) {
try {
if (
f[i] /*/iframedAppPanel*/ &&
f[i].length &&
f[i][0] && //#sandboxFrame
f[i][0][0] && //#userHtmlFrame
window !== f[i][0][0] //!== self
) {
console.info('Sidebar found ');
var sidebar = f[i][0][0];
sidebar.modalDone(document.getElementById("category").value);
}
} catch (e) {
console.error(e);
continue;
}
}
};
function afterAddNewClicked(){
findSideBar(10);
google.script.host.close();
}
document.getElementById("btn-add-new").addEventListener("click", afterAddNewClicked);
</script>
</body>
EDIT:
modal.html now has the function findSidebar
sidebar.modalDone = document.getElementById("category").value
res or modalDone needs to be called. Just assigning a value won't work. Try
sidebar.modalDone(document.getElementById("category").value);

onclick in javascript not triggering, while Id is correct

this is my javascript code the onclick functions do not trigger when i push the button I have tried with an event listener that listen only for the parent of the button aka the form but nothing in that case it fires once and it does not keep listening for further button clicks:
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
document.addEventListener('DOMContentLoaded', () =>{
const room__message = Handlebars.compile(document.querySelector('#room__message').innerHTML);
document.querySelector('#send__button').onclick = () =>{
console.log('hola el boton fue pulsado')
let message = document.querySelector('#message__input').value
let user = localStorage.getItem('user')
let channel = localStorage.getItem('channel')
console.log(message)
socket.emit('send message', {'message':message, 'user':user, 'room':channel})
document.querySelector('#message__input').value = '';
}
socket.on('connect', () =>{
socket.emit('join', { 'channel':localStorage.getItem('channel'), 'user':user })
load__list();
load_messages(localStorage.getItem('channel'))
});
document.querySelector('#add__room').onclick = () => {
let list = JSON.parse(localStorage.getItem('channel__list'));
let name_ = prompt("Please enter you'r new Channel's name", "");
while (name_ in list || name != null){
name_ = prompt("this name is already in the database", "");
}
if (name_ != null){
list.push(name_)
}
socket.emit('new room', {'name':name_})
};
socket.on('broadcast', data =>{
let message = data.message;
let user = data.user;
let timestamp = data.timestamp;
const msj = room__message({'message':message, 'user':user, 'timestamp':timestamp})
document.querySelector('.message__cont').innerHTML += msj;
});
});
the html looks like this:
<body>
<ul id="channel__list">
<li>
<button id="add__room">+</button>
</li>
</ul>
<div id="chanel__container">
<form id="channel__form" action="" >
<input type="text" id="message__input" autocomplete="off" placeholder="message">
<input type="submit" id="send__button" value="send">
</form>
</div>
</body>
it does run in a flask server I dont know if that may be an issue
First of all, there are quite a few syntax errors in your code.
Inside your HTML code
<from> tag is to be changed to <form>
Inside your JS code
ID room__message is not declared hence this will never return anything.
You have opened a function socket.io('connect') function but never closed.
Coming back to why the on click buttons are not getting triggered *
The possible reason this could be happening is that by the time your document readyState is already completed in this case the event DOMContentLoaded will not be fired at any point in time. This can be avoided by providing/checking document ready state.
Below are two sample codes (I am still not sure why you are using on click function inside a listener while you can use JS shorthand and directly use it)
Proper HTML code
<body>
<ul id="channel__list">
<li>
<button id="add__room">+</button>
</li>
</ul>
<div id="chanel__container">
<form id="channel__form">
<input
type="text"
id="message__input"
autocomplete="off"
placeholder="message"
/>
<input type="submit" id="send__button" value="send" />
</form>
</div>
</body>
Your actual JS code (a bit modification)
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", loadDomContent());
} else {
console.log("Current document load state: ", document.readyState);
loadDomContent();
}
function loadDomContent() {
const room__message = Handlebars.compile(
document.querySelector("#room__message").innerHTML
);
document.querySelector("#send__button").onclick = () => {
/* do something */
};
socket.on("connect", () => {
socket.emit("join", {
/* do other stuff }); */
});
});
document.querySelector("#add__room").click = () => {
console.log("I am working");
/* do something else */
};
socket.on("broadcast", data => {
/* send some stuff over */
});
}
Also, you can write something like this
<button onclick="addNewRoom()" id="add__room">+</button>
An declaring that as:
function addNewRoom(){
// do something
}
My Solution
the issue was in deed in the html, because it was changing the position of th ebutton by adding more elements to its container im guessing it changed the address to which the event was pointing at, thanks everybody for their input.

Diable the button , enable button after another button clock

I want that until the Copy List To Below get clicked I want to disable to Save button.
Currently this is the Copy List To Below button
<button type="button" className={classes["copy-btn"] + " btn-cancel mt-3"} onClick={(event) => this.copyData(event)}>Copy List To Below {_.size(this.state.protestList) > 1 ? _.size(this.state.protestList) + " Groups" : 'Group'} </button>
And this is my Save button
<button type="submit" className={classes["save-btn"] + " btn-save"} onClick={(event) => this.saveData(event)}>Save</button>
And below is the respected functions
saveDate = (event, data) => {
if(event) {
//Do something
}
else {
//Return Error
}
}
copyData = (event, data) => {
if(event) {
//Do something
}
else {
//Return Error
}
}
As I said only if Copy is done then only save button should be able get clicked
Give two ids and add click event and toggle button disable property like this. Make it simple. Your buttons has unnecessary attributes, please remove those.
CORE JAVASCRIPT
<button type="button" id="coptBtn" class ="btn-cancel mt-3" >Copy List To Below</button>
<button id="saveBtn" type="submit" class="" >Save</button>
var coptBtn = document.getElementById('coptBtn');
var saveBtn = document.getElementById('saveBtn');
saveBtn.disabled = true;
coptBtn.addEventListener('click', (evt) => {
saveBtn.disabled = false;
});
REACT JS
var App = React.createClass({
getInitialState() {
return {isDisable: false}
},
handleClick(e) {
this.setState({isDisable: true})
},
render() {
return <div>
<button type="button" onClick={this.handleClick} >Copy List To Below</button>
<button type="button" disabled={!this.state.isDisable}>Save</button>
</div>
}
});
Try this code..
copyData() {
//your existing code
this.setState({copied: true})
}
<button type="submit" disable={!this.state.copied} className={classes["save-btn"] + " btn-save"} onClick={(event) => this.saveData(event)}>Save</button>

Ng-Class doesn't detect changes

On page I have ng-repeat which iterates through items in collection. Every item has property status according to which I add some class or don't. And every item has button, onclick it change item status and make PUT request to API.
As my collection on page is updated every 2 minutes, I have problem after few updates. After 5-6 minutes I make click on button, which make PUT request (successful), but my ng-class function doens't detect that status of item is changed.
<div class="one-third" ng-repeat="request in requests track by request.id">
<div class="incoming_request" ng-class="actionClass(request)">
<h2 ng-class="DayTypesClasses[request.typeId]" ng-bind="request.type"></h2>
<hr>
<div class="request_description">
<p><span>Description:</span></p>
<p ng-bind="request.baseComment"></p>
</div>
<div class="request_resolve">
<hr>
<div class="textarea-holder">
<textarea placeholder="Your comment..." ng-model="request.newComment" ng-model-options="{ updateOn: 'default blur'}"></textarea>
</div>
<div class="button-container">
<button ng-click="approve(request);" class="btn btn-primary">Confirm</button>
<button ng-click="reject(request);" class="btn btn-default pull-right" am-hide-request-resolve-div>Reject</button>
</div>
</div>
</div>
</div>
and JS-code
$scope.approve = function (request) {
var status = State.APPROVED;
var currentUserComment = request.comments.filter(function(comm) {
return comm.userId == user.id && comm.status == "Pending";
})[0];
currentUserComment.status = status; //change status
currentUserComment.text = request.newComment;
delete request.newComment;
if (!currentUserComment) {
request.isProcessing = false;
return;
}
Comments.update(currentUserComment, function() {
// $rootScope.$broadcast('daysUpdated');
});
request.isProcessing = false;
};
Ng-class function :
$scope.actionClass = function(request) {
var currentUserComment = request.comments.filter(function(comment) {
return comment.userId == user.id;
})[0];
//after click here status for every item isn't changed. Tested in debug mode
if (!currentUserComment || currentUserComment.status == State.APPROVED || currentUserComment.status == State.REJECTED) {
return 'you-approved';
}
}
So as result after few updates of my collection (requests collection I mean) onclick js isn't able to add class you-approved.
I've missed one imporatnt detail - I change status not to item request but for item, that exists in request.comments. So I can't just write ng-class="{'you-approved': request.approved}"
As #Cyril suggested I've tried to use this peace of code in my controller
$scope.$apply(function(){$scope.requests = CurrentUserData.getRequests();}) but receive error $digest already in progress.
Also I've tried to use angualr service $interval instead of window.setInterval function that updates collection requests every 2 minutes, but it doesn't seem to help.
have a look at:
https://docs.angularjs.org/api/ng/directive/ngClass
your ng-class expression doesnt need to return the class property but a json that holds the class name with a condition
so change
<h2 ng-class="DayTypesClasses[request.typeId]" ng-bind="request.type"></h2>
to:
<h2 ng-class="{'you-approved': request.approved}" ng-bind="request.type"></h2>
and JS-code update the approved parameter
How about:
ng-class="{'you-approved': !currentUserComment || currentUserComment.status == State.APPROVED || currentUserComment.status == State.REJECTED}"
Here is an example of that logic using a plunker:
https://plnkr.co/edit/hoTnrLBAibMJ0wd2WMzm?p=info
HTML:
<button ng-click="setApproved()">Set Approved</button>
<button ng-click="setRejected()">Set Rejected</button>
<button ng-click="setSomethingElse()">Set Something Else</button>
<hr />
<span ng-class="{'you-approved': !currentUserComment || currentUserComment.status == 'approved' || currentUserComment.status == 'rejected'}">Test</span>
Controller JS:
$scope.setApproved = function(){
$scope.currentUserComment = {
status: 'approved'
}
}
$scope.setRejected = function(){
$scope.currentUserComment = {
status: 'rejected'
}
}
$scope.setSomethingElse = function(){
$scope.currentUserComment = {
status: 'somethingElse'
}
}
https://docs.angularjs.org/api/ng/directive/ngClass

Categories

Resources