DOM not updating until page is refreshed - javascript

I have an asynchronous method that calls a web api to retrieve json data.
I then use the json data to fill in a few `' boxes. However, the values do not appear in the text boxes until I refresh the page?
The HTML:
<form>
<h1 id="OrderNameHeader"></h1>
<div class="dataitemdiv">
<p class="dataitemlabel">Quantity:</p>
<input id="quantitytb" type="text" readonly="readonly" class="dataitemtextbox" />
</div>
<div class="dataitemdiv">
<p class="dataitemlabel">Delivery Date:</p>
<input id="deldatetb" type="text" readonly="readonly" class="dataitemtextbox" />
</div>
</form>
The Javascript:
function SearchOrder() {
var OrderName = document.getElementById("SearchTextBox").value;
var frurl = 'order/getbyname/' + OrderName;
var api = new GetJSON(frurl);
var obj;
obj = api.CallAPI().done(function (data) {
//alert('Quantity: '+data.Quantity +' & Delivery Date: ' + data.DeliveryDate);
var onh = document.getElementById("OrderNameHeader");
onh.title = data.OrderName;
document.getElementById("quantitytb").value = data.Quantity;
document.getElementById("deldatetb").value = data.DeliveryDate;
});
}
Its worth noting at this point that the line: alert('Quantity: '+data.Quantity +' & Delivery Date: ' + data.DeliveryDate); works perfectly fine?
Do I have to do some manual refresh of the page in the Javascript or is there something else I am missing
Update:
Just to add some extra information, I've done some more debugging and I can see that neither the data.~ or the element i'm trying to modify is undefined, they both have values.
Tested this on all major browsers (minus safari).

Related

How to display values from google script object in html <p>?

HTML code
I want to display object values in this form in <p or easier solutions
<div class="control-form-id">
<label for="id">Id:</label>
<input type="text" name="id" id="id" required>
<button type="button" onclick="JSinHTML();" id="search" >Search</button>
</div>
<div class="serial">
<label for="serial">Serial number:</label>
<p id="serial">result</p>
</div>
<script>
function JSinHTML(){
let id_form ={}
id_form.input = document.getElementById("id").value
alert(id_form.input);
google.script.run.main(id_form);
document.getElementById("id").value = "";
}
</script>
GOOGLE SCRIPT code
function findId returns row number by typed id
function main(JSinHtml){
let numberRow = findId(JSinHtml.input);
Logger.log("input in main " + JSinHtml.input);
let toHtml = {};
toHtml.id = sheet_spis.getRange(numberRow, column_id).getValue();
toHtml.serial_number = sheet_spis.getRange(numberRow, column_serialnr).getValue();
toHtml.size = sheet_spis.getRange(numberRow, column_size).getValue();
toHtml.type = sheet_spis.getRange(numberRow, column_type).getValue();
Logger.log(toHtml); //I want to display separately this values in few <p>
}
In your situation, how about the following modification?
HTML & Javascript side:
From
google.script.run.main(id_form);
To:
google.script.run.withSuccessHandler(e => {
document.getElementById("serial").innerHTML = e.serial_number;
}).main(id_form);
Google Apps Script side:
From
Logger.log(toHtml); //I want to display separately this values in few <p>
To:
Logger.log(toHtml);
return toHtml;
Note:
From <p id="serial">result</p>, I guessed that you might have wanted to put the value of serial_number. So, I proposed it. If you want to show the whole object of toHtml, please modify document.getElementById("serial").innerHTML = e.serial_number; to document.getElementById("serial").innerHTML = JSON.stringify(e);.
Reference:
withSuccessHandler(function)

Program is treating the same string differently when entered into a different text box

I have a program that is supposed to group links together. Like minecraft saved toolbars, you can save a collection of links, then enter in the name of a group and it will open all of them.
But my program is having trouble with getting the list from localStorage when the name is entered into the text box meant to get the link. But when I just use the value of the text box meant to name the group, it works fine.
My code is here:
var groupName = document.getElementById('name');
var link = document.getElementById('newLink');
var linkCounter = 0
var getByName = document.getElementById('getByName').value
function startGroup() {
localStorage.setItem(groupName.value, groupName.value);
console.log(localStorage.getItem(groupName.value))
}
function addLink() {
linkCounter++;
localStorage.setItem(groupName.value + '_link' + linkCounter, link.value);
console.log(localStorage.getItem(groupName.value + '_link' + linkCounter))
}
function saveGroup() {
localStorage.setItem(groupName.value + '_length', linkCounter);
console.log(localStorage.getItem(groupName.value + '_length'))
alert(groupName.value);
}
function getGroup() {
// if I replace getByName with groupName.value, it works fine.
var len = localStorage.getItem(getByName + '_length')
console.log(len)
for (var x = 1; x <= len; x++) {
window.open(localStorage.getItem(getByName + '_link' + x));
}
}
<!DOCTYPE html>
<html>
<a href='readit.html'>READ THIS BEFORE USING</a>
<p>WHEN ADDING A LINK YOU NEED TO PASTE IT OR ADD HTTPS:// TO THE BEGINNING OF THE LINK.</p>
<div id='toolbars'>
<p>Open a group!</p>
</div>
<div id='create'>
<p>Create some bookmark groups!</p>
<input type='text' placeholder='name your group' id='name'>
<button onclick='startGroup()'>Let's add some links!</button>
<br>
<input type='text' placeholder='add a link' id='newLink'>
<button onclick='addLink()'>Submit</button>
<br>
<button onclick='saveGroup()'>SAVE</button>
</div>
<div id='preview'>
<br><br>
<button onclick='getGroup()'>Open this group</button>
<input type="text" id="getByName">
</div>
</html>
<script src="script.js"></script>
You are reading the value of the getByName input element at page load. Instead you should read the value at the time of need. So define getByName as the DOM element (not as its value):
var getByName = document.getElementById('getByName');
And where you currently reference getByName, suffix the .value property accessor. For instance:
var len = localStorage.getItem(getByName.value + '_length');
Side note: I find it easier to use a memory data structure for all your data, and when something is added to it, to write that complete data structure to one single local storage key, JSON formatted. You may want to look into that.

I am trying to refresh the div without refreshing the entire page using $( "#div" ).load(window.location.href + " #div" ); it is not working

I am trying to refresh this div but I keep getting this error XMLHttpRequest cannot load. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
I have researched that firefox had allowed cross http requests but when I reload the page the div disappears.
I am wondering if there is something wrong with my codes.
The data that I am retrieving is from firebase.
function updateDiv(){
$("#data-container").load(window.location.href + " #data-container");
}
<div data-role="page" id="pageone">
<div data-role="header">
<button onclick="goBack()">Back</button>
<h1>Transaction History</h1>
</div>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for Name..">
<button onclick="updateDiv()"></button>
<div id="data-container"></div>
You're calling a load on the actual page (window.location.href) for the content of #data-container, and you want to put the content into #data-container. On your code, the content of #data-container is empty, so you replace "empty" by empty". I don't know what you really want to do ?
For your Cross Origin problem you should try to call a relative path instead of window.location.href. For example if you're on http://localhost/test.php you should write .load('test.php #data-container').
Can you explain a bit what your are trying to do ? What do you call "refresh the div" ? You want to restore it's content with original content, because it can be modified after page load (with JS for example) ? If yes, you should store the initial content of the div in JS cache :
jQuery(document).ready(function(){
jQuery('#data-container').data('cache',jQuery('#data-container').html)) ;
}) ;
Then when you want to restore it's original content, you don't have to make an ajax call, you just have to get the stored content :
function updateDiv(){
$("#data-container").html(jQuery('#data-container').data('cache'))
;
}
But, tbh, i think this not what you're trying to do, right ? You're trying to search for datas containing jQuery('input#myInput').val() ?
This is what I have on page load it will retrieve all the transaction from firebase and update accordingly to the list.
firebase.auth().onAuthStateChanged(function(user) {
// [START_EXCLUDE silent]
// [END_EXCLUDE]
if (user) {
uid = user.displayName;
console.log(uid);
var rootRef = firebase.database().ref();
var ref = rootRef.child(uid + "/Transaction History");
var query = ref.orderByKey().limitToLast(100);
query.on("child_added", function(messageSnapshot) {
// This will only be called for the last 100 messages
var keys = Object.keys(messageSnapshot);
var messageData = messageSnapshot.val();
var key = messageSnapshot.getKey();
console.log("key is " + messageSnapshot.getKey());
console.log("messagesnapshot is " + messageSnapshot);
var obj = {
key: key,
firstName: messageData.firstName,
lastName: messageData.lastName,
icNo: messageData.icNo,
passportNo: messageData.passportNo
};
arr.push(obj);
ref.child(key + "/User Information").once('value').then(function(snapshot) {
var name = snapshot.val().firstName;
console.log(name);
s = "<li><a href='#'>" + no + '. '+ name + ' ' + key +"</a></li>";
no++
sources.push(s)
// for ( property in messageSnapshot) {
// console.log( property ); // Outputs: foo, fiz or fiz, foo
//}
//$("#mylist").html(s);
//$("#mylist").listview("refresh");
console.log("arr.length is " + arr.length);
console.log(sources[9]);
}).then(function(pagination) {
Pagination();
})
After pressing the button it will refresh the div with the newly updated transactions that are retrieved from firebase in the data container
function updateDiv(){
$( "#data-container" ).load(window.location.href + " #data-container" );
}
</script>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<button onclick="goBack()">Back</button>
<h1>Transaction History</h1>
</div>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for Name..">
<button onclick="updateDiv()"></button>
<div id="data-container"></div>
<div id="mylist"></div>

Dynamically duplicated forms disappear on CodeIgniter reload

I have the following code that needs to be duplicated:
<form method="post">
<div id="field-row-container">
<div id="field-row-1" class="field-row">
<div class="field-element">
<label for="Name[1]">Name</label>
<input type="text" id="Name[1]" name="Name[]" />
</div>
<div class="field-element">
<label for="Email[1]">Email</label>
<input type="text" id="Email[1]" name="Email[]" />
</div>
<hr/>
</div>
</div>
<div class="form-element">
<input type="button" class="confirm add-field-row" value="Add" />
<input type="button" class="danger delete-field-row" value="Delete" />
<input type="submit" />
</div>
The duplicated / dynamically added elements will have the same names of Name[] and Email[] but their ID's will be incremented.
The JavaScript is below, based from Josiah Ruddell's form duplication script.
var template = $('#field-row-container #field-row-1').clone();
window.addForm = function () {
var parent = $(this).closest('.dynamic-rows').attr('id');
var fieldRowCount = countRows(parent) + 1;
var newFieldRow = template.clone().find(':input').each(function () {
var newId = this.id.substring(0, this.id.length - 3) + "[" + fieldRowCount + "]";
$(this).prev().attr('for', newId); // update label for
this.id = newId; // update id and name (assume the same)
$(this).closest('.field-row').addClass('new-row');
}).end()
.attr('id', 'field-row-' + fieldRowCount)
.appendTo('#field-row-container');
}
$('.add-field-row').click(addForm);
Whenever I submit the form to CodeIgniter and if there is a validation error, once the controller reloads the multi-part form, the dynamically added elements disappear as well as the values in the initial fields.
How do I go around this problem? I'm at a loss on how to solve this...
Other notes that might help:
This is a component multi-part form with only one form controller
I have multiple instances of this - Addresses, Education Degrees and such
I use CodeIgniter's form_validation library to check server-side each array of posts
When the page with the form on reloads after the controllers redirects back to it after failing validation, it will only reload the original page, with no DOM manipulations applied.
I would perform the POST request which submits the form via ajax, so you can handle the response without leaving the page. Something like this:
$.post('/locationOfController.php', $('#yourForm').serialize(), function(response){
if(response.valid){
window.location.href = '/somewhereAfterFormPosted.php';
} else {
$('#yourForm').append("<p>"+response.error+"</p>");
}
}, 'json');
and change the controller to return a JSON object based on whether validation passed or not. To match up with my example above, you would return something like below when an error occurs:
{valid: false, error: 'Please fill out the whole form'}
Try something like that as a basic example. You could do much more, such as returning several errors if multiple fields are invalid.

Build JSON based on this requirement, can I use jQuery

I'm not sure how to write this JS, so ask for help here!
HTML
<div class="grid_18" id="reference_container">
<div class="grid_16">
<fieldset>
<legend>Website</legend>
<span class="grid_2">Person</span>
<input name="person" class = "grid_6" type="text" />
<span class="push_2">Year</span>
<input class="push_2" name="year" type="text" />
</fieldset>
</div>
<div class="grid_16">
<fieldset>
<legend>Newspaper</legend>
<span class="grid_2">Author</span>
<input name="author" type="text" />
<span class="push_4">Year</span>
<input class="push_4" name="year" type="text" />
</fieldset>
</div>
</div>
What I need is a list of JSON one for each fieldset. The result will look like this:
[
{type:"website" , person: "(Based on user input)", year: "(Based on user input)"},
{type:"Newspaper", author: "(Based on user input)", year: "(Based on user input)" }
]
(type is static, the content comes from legend, other fields are not the same)
One thing need to notice is that the field name is not static(person, author etc..), need to pick up from name attribute.
This looks challenge for me, hope who can help with this~
var json = JSON.stringify($('fieldset').map(function () {
var self = $(this);
var obj = {
type: self.children('legend').text()
};
// Find each input element with a name attribute, and add the name/val to the object
self.find('input[name]').each(function () {
obj[this.name] = this.value + " (Based on user input)";
});
// Return the object we've constructed
return obj;
}).get());
map: Executes the provided function on each matched element, and returns a new jQuery object whose elements are the returned value of the function for each element.
get: Returns the jQuery object as an array.
Be sure to include the JSON library from https://github.com/douglascrockford/JSON-js, to support browsers which do not include the JSON library.
I have a solution that doesn't require json2.js. It uses jQuery's serialize() method and replaces the query string characters with valid JSON delimiters instead:
var arr = [];
$("fieldset").each(function () {
var $this = $(this),
serialized = $this.children("input").serialize(),
type = $this.children("legend").text();
// Replace the jQuery-serialized content into valid JSON
serialized = serialized.replace(/([^=]+)=([^&]*)(&)?/g, function ($0, name, val, amp) {
return '"'+name+'":'+'"'+val+'"' + (amp ? "," : "");
});
// Add it to the array
arr.push('{"type":"'+type+'",'+serialized+'}');
});
// Join the array into a valid JSON string
var json = "[" + arr.join(",") + "]";
There's a working demo here: http://jsfiddle.net/AndyE/ASrKN/
Note that it doesn't re-decode the result (for instance, if the user input has characters that should be url-encoded), but you would probably want these to stay encoded if you're posting to the server anyway.

Categories

Resources