I press a button/image to run script that opens the picker. I can select an existing folder and I have added a field to create a new folder (within the selected existing folder).
All of this works as I want, but I added some error handling incase the button to create a new folder was pressed without a folder name being given. I put the message in an alert (may need to amend that as it gives the option to 'prevent this page from displaying additional dialogues') but once the alert has gone, the html disappears.
What do I do to retain the HTML that was in the IFRAME before the button was pressed?
This is my HTML code and the function behind the button.
</head>
<body>
<div>
<p> Please select the property you wish the ticket folder to be created in. </p>
<button onclick='getOAuthToken()'>Select a Folder</button>
<br>
<p> (If it does not exist, select the folder you wish to create a new location in.) </p>
<p id='result'></p>
</div>
<script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
<br><br><br>
<div id="frmCreate" style="display:none">
<form>
<label class="hiddenfrm"> Folder Name: </label><input type="text" id="newFdrNm" class="hiddenfrm">
<button onclick='makeFolder()' class="hiddenfrm">Create New Folder</button>
<p id='newresult' class="hiddenfrm"></p>
</form>
</div>
</body>
</html>
//function to create a folder in the selected folder
function makeFolder() {
var ParentFolder = document.getElementById('PFldrID').innerHTML
var NewFolderName = document.getElementById('newFdrNm').value
if (NewFolderName == "") {
alert("Folder Name Required!")
}
else {
google.script.run.CreatePropertyFolder(NewFolderName, ParentFolder);
google.script.host.close();
}
}
EDIT:
After removing the form tags, the dialogue box works as required.
For the alert, I decided to have the error message display under the text box.
Amended parts of the code:
*HTML*
<button onclick='makeFolder()' class="hiddenfrm">Create New Folder</button>
<br><span id="newFdrNmError"></span>
*script*
if (NewFolderName == "") {
document.getElementById('newFdrNmError').innerHTML = "Error: You must 'name' the new folder!";
return false;
}
The HTML in the window is disappearing because the "Create New Folder" button is inside of the <form> tags. There is nothing that I know of that can stop that from happening, except moving the button outside of the <form> tags.
Move button:
<form>
<label class="hiddenfrm"> Folder Name: </label><input type="text" id="newFdrNm" class="hiddenfrm">
<p id='newresult' class="hiddenfrm"></p>
</form>
<button onclick='makeFolder()' class="hiddenfrm">Create New Folder</button>
Related
My apologies for the stupid question, but I am trying to change the name of a button upon uploading a file. My code to change it is this, via TypeScript:
const i = (document.querySelector('label') as any).innerText = filename;
The code above, inside the fileName method, changes the "Upload Project File" text into the name of whatever file that is uploaded.
<div class="row">
<div class="clg6 cmd8 csm10 cxs12" v-if="this.projectFile">
<button
class="button primary outline medium upload">
<label>
<input
type="file"
name="projectFile"
id="fileName"
accept=".xls, .xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
v-on:change="validateFileType(); hashContentMD5(); fileName; getPresignedURL()"/>
<i class="fas fa-cloud-upload"></i>
Upload Project File
</label>
</button>
</div>
</div>
And it works. However, upon change, it brings up errors in my other methods when they're called, such as this:
const file = (document.getElementById('fileName')as any).files[0]
The error that shows up is
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'files')
Removing the document.querySelector removes the error. This is the first time that I've encountered this. How can I fix it?
Problems:
You put your input inside the label tag. I learned this is okay.
Why using a button outside the whole label and input tags? I don't understand what your intention was with that.
You replace the inside of the label tag by a text node (containing the file name). Through your replacement you delete your input field out of the DOM. See querySelector line in your code.
After having replaced the input field, there is no fileName on the page anymore, so it getElementById results in null.
Solution:
(optionally) I'd delete the button tag and only keep the inside of it.
Don't operate on that label and don't try to overwrite the value of a file input field
By not removing the input field anymore, you can access it and read out the file name
See my example here: https://stackblitz.com/edit/js-fdxxnf
You can try with ref:
new Vue({
el: '#demo',
data() {
return {
projectFile: true
}
},
methods: {
changeLbl() {
this.$refs.lab.innerText = 'filename'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="row">
<div class="clg6 cmd8 csm10 cxs12" v-if="projectFile">
<button
class="button primary outline medium upload">
<label ref="lab">
<input
type="file"
name="projectFile"
id="fileName"
accept=".xls, .xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
v-on:change="changeLbl"/>
<i class="fas fa-cloud-upload"></i>
Upload Project File
</label>
</button>
</div>
</div>
</div>
I have popup in HTML
<div id="term_flags" class="term_flags">
<div class="modal-users-content flagsContent">
<div class="modal-users-header">
<span class="close" ng-click="closeFlagsPopup()">×</span>
<a> Check terminal flags </a>
</div>
<div class="modal-flags-body">
<div class="checkBoxes">
<div class="checkerDiv">
<input type="checkbox" ng-model='reservedFlag' ng-click='changeReservedStatus(reservedFlag)' value="flag" ng-checked="reservedFlag"> Reserved
</div>
<div class="checkerDiv">
<input type="checkbox" ng-model='seasonFlag' ng-click='changeSeasonStatus(seasonFlag)' value="flag" ng-checked="seasonFlag"> Season
</div>
<div class="checkerDiv">
<input type="checkbox" ng-model='networkFlag' ng-click='changeNetworkStatus(networkFlag)' value="flag" ng-checked="networkFlag"> Network
</div>
</div>
<div class="saveFlags">
<button class="button button6" name="changeFlags" value="Change Flags" type="submit" ng-click="saveFlags(item.terminalId)"> Save <p> </button>
</div>
</div>
<div class="modal-footer"></div>
</div>
</div>
this div's display is none in the beginning. but some ng-click is called from outside of this div and display is changed from none to block and initializes checkbox statuses in this angular function
$scope.changeFlagStatus = function(item)
{
$scope.reservedFlag=(item.reservedFlag=='T')?true:false;
$scope.networkFlag=(item.networkFlag=='T')?true:false;
$scope.seasonFlag=(item.seasonFlag=='T')?true:false;
document.getElementById('term_flags').style.display = "block";
}
everything is okay , but when i click on reservedFlag changeReservedStatus(reservedFlag) method was called and change reservedFlag's checked status
$scope.changeReservedStatus = function(item) {
$scope.reservedForSave=item;
}
I saved this status in other variable and close my popup windows document.getElementById('term_flags').style.display=none
when i open this popup window again my function changeFlagStatus(item) is called again and initializes my variables for checkbox correctly but my checkbox are incorrect checked .
In example when i opened my popup window first time my variables after initialize were
$scope.reservedFlag=true;
$scope.networkFlag=false;
$scope.seasonFlag=true;
and my checkbox statuses were
reservedFlag = checked
networkFlag = unchecked
seasonFlag = checked
then i clicked on reservedFlag and changed his status from checked to unchecked and close my popup windows.
then i opened it second time and changeFlagStatus(item) method is called again to initialize my variables again for checkbox statuses
and i want to get
reservedFlag = checked
networkFlag = unchecked
seasonFlag = checked
again, but result is
reservedFlag = unchecked
networkFlag = unchecked
seasonFlag = checked
How can i get it ?
Angularjs won't work pretty good with $scope's properties for primitive variables when used again and again.
I would recommend you to declare an object to scope and set these flags as properties to this object.
$scope.flags = {};
$scope.changeFlagStatus = function(item)
{
$scope.flags.reservedFlag=(item.reservedFlag=='T')?true:false;
$scope.flags.networkFlag=(item.networkFlag=='T')?true:false;
$scope.flags.seasonFlag=(item.seasonFlag=='T')?true:false;
document.getElementById('term_flags').style.display = "block";
}
and the html part as
<input type="checkbox" ng-model='flags.reservedFlag' ng-change='changeReservedStatus()' value="flag" ng-checked="flags.reservedFlag"> Reserved
Instead of ng-click, I would recommend to use ng-change because that is the event to be used with checkbox. If you use ng-change, the injection of the model as a parameter can be avoided which helps in utilizing angularjs's feature of 2-way binding.
You can add ng-true-value and ng-false-value to the checkbox with true and false to make it more easier to handle instead of ng-value.
I would write the html part like this.
<input type="checkbox" ng-model='flags.reservedFlag' ng-change='changeReservedStatus()' ng-true-value="true" ng-false-value="false"> Reserved
Hope this will fix the issue.
More exactly I want when I press enter to put my line in <p> for example:
<p>HELLO</p>
<p>Another line</p>
<p>Line 3</p>
To upload like this in database
Here is my code where I want to do this
<div class="form-group">
<label for="phone-pin">Text</label>
<textarea type="text" class="form-control" id="text-area-first" name="text-area-first" required placeholder="text"></textarea>
</div>
Here is a solution.
function store() {
var txt = document.getElementById("text-area-first").value;
var txttostore = '<p>' + txt.replace(/\n/g, "</p>\n<p>") + '</p>';
console.log(txttostore);
}
<div class="form-group">
<label for="phone-pin">Text</label>
<br>
<textarea type="text" class="form-control" id="text-area-first" name="text-area-first" required placeholder="text"></textarea>
<br>
<button id="store" onclick="store()">Store</button>
</div>
You can do this by using javascript onkeypress event.
As we know Enter has keycode 13 then match that keycode and do your work.
Assign the value to a variable and store that variable into database.
<html>
<body>
<textarea name="text" id="texta" onkeypress="myFunction(event)"></textarea>
<p id="demo"></p>
<script>
function myFunction(event) {
var x = event.keyCode;
var res;
if(x==13){
res="<p>" + document.getElementById("texta").value +"</p>";
document.getElementById("demo").innerHTML = res;
}
}
</script>
</body>
</html>
Hope it will help.
Just out of curiosity, are you trying to get new line to save to your database?
If so and you using php. You could just do
$a=nl2br($_POST('text-area-first'));
That will save the <br> tag in your db
So every time you hit enter in your textarea it will also save the <br> tag.
Hrk! A couple of these are close, but consider that you need three different components.
Put an ID in the p tag where you want to put the text and the input which will be the source of the text. This is necessary because in the Javascript you will need to find each of them.
<p id="waitingForText"></p>
<input type="text" id="textSource"></input>
You need to have an event which will trigger the process of storing the text in the paragraph. I think Pirate has a great suggestion using the enter key. Pugazh suggested a button. I have included both here. Please note that I have added the onkeypress event to the same input tag described in step 1.
<button onclick="TextEvent()">Click</button>
<input type="text" id="textSource" onkeypress="KeyEvent(event)"></input>
The final step is the script which ties it all together. In this case we will have a function to catch the enter key (per Pirate's idea) and then unify that with the function called by the button. It is important to do this because we will only have one function with code which stores the text.
<script>
function TextEvent()
{
var destination = document.getElementById("waitingForText");
var source = document.getElementById("textSource")
destination.innerHTML = source.value;
}
function KeyEvent(event)
{
if(event.keyCode==13)//as Pirate suggests or any other char
{
TextEvent();//call the same method to move text
}
}
</script>
That's it.
Given this code:
<div ng-controller="MyCtrl">
<form ng-submit="onSubmitted()">
Header inputs:
<input type="name" ng-model="sample" required/>
<input type="name" ng-model="sampleX" required/>
<input type="submit" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
</form>
<hr/>
Some other form here. Think line items
<hr />
<a class="btn" ng-click="/* what could should be put here, so this can trigger the firt form's validation, then submit? */">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>
</div>
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.onSubmitted = function() {
alert('submitted!');
};
}
I want the last button to trigger the validation(then submit when things are valid) on first form. As of now, only the button inside the form can trigger that form's validation and submission. Is there any possible way for a button outside the form to do that?
Live test: http://jsfiddle.net/dzjV4/1/
You can create directive which you can then attach to <a class="btn".... Check this jsfiddle
http://jsfiddle.net/dzjV4/2/
Note that I added to <input type='submit' id='clickMe'... and linked it with link at the bottom <a class='btn' linked="clickMe"...
for (control of $scope.[form name].$$controls) {
control.$setDirty();
control.$validate();
}
You can try the above codes. Make it running before submit.
Ideally there'd be a programmatic way to cause validation to re-run across a form. I have not investigated that completely but had a situation that required multiple controls to be re-validated based on different data in the scope -- without the user interacting with the individual controls. This arose because the form had two action buttons which each required different validation rules be in play when they were clicked.
The UI requirement changed before I fully implemented forcing re-validation but before it did I got most of what I needed by copying and then re-setting the form's data. This forced re-validation across the form within the current scope. Basically, it's along the lines of the following (not tested, but taken from the code that was working). In this case the form's data was bound to the properties in one object.
var formData = $parse(<form's model>);
var dataCopy = angular.copy( formData($scope) );
formData.assign( $scope, dataCopy );
This may or may not be acceptable, but if you can get away with the SUBMIT button being disabled until the form is completed, you can do this:
<form name="formName">
<input ng-required="true" />
</form>
<button ng-click="someFunction()" ng-disabled="formName.$invalid" />
It's also worth noting that this works in IE9 (if you're worried about that).
Give your form a name:
<div ng-controller="MyCtrl">
<form name="myForm">
<input name="myInput" />
</form>
</div>
So you can access your form validation status on your scope.
app.controller('MyCtrl', function($scope) {
$scope.myForm.$valid // form valid or not
$scope.myForm.myInput // input valid or not
// do something with myForm, e.g. display a message manually
})
angular doc
There is no way to trigger browser form behavior outside of a form. You have to do this manually.
Since my form fields only show validation messages if a field is invalid, and has been touched by the user:
<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">
<!-- field label -->
<label class="control-label">Suffix</label>
<!-- end field label -->
<!-- field input -->
<select name="Parent_Suffix__c" class="form-control"
ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
ng-model="rfi.contact.Parent_Suffix__c" />
<!-- end field input -->
<!-- field help -->
<span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
<span ng-message="required">this field is required</span>
</span>
<!-- end field help -->
</div>
<!-- end form field -->
I was able to use this code triggered by a button to show my invalid fields:
// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
angular.forEach(error, function(field) {
field.$setTouched();
});
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
isValid = false;
}
I have a problem with json. I'd like to display the result of my form in the new browser window in JSON. (When user fills all fields in the form, button becomes enabled and shows JSON in specified format (I did it)). I translated it in JSON but dunno how to output it...I'm thinking of create new html page and do window.open on button on 1st page, but then it doesn't read data from 1st page which user entered. Or should I save it somehow in JSON file and then read it from other page?
For example:
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button type="submit" id="btn" class="btn" disabled="disabled">Submit</button>
</form>
I have some form with date field and button:
I can easily get JSON of date field by {{date | json}} on the same page, but I just want to output it in new browser window. How can I do this? Please help me with some tips. Thanks.
If it's not too big you can send the information to the new window as a data URL.
The frame will be reused once it is open.
This might be a start, showing how to plug in the JSON data and break it up over multiple lines for display.
window.open('data:application/json,'
+JSON.stringify(location).replace(/([[{,])/g, "$1%0a"),
'jsonFrame',
'resizeable,top=100, left=100, height=200, width=300,status=1')
See MDN for all the details.
You should be able to get at the window.opener from the new window and parse values out of it. The following plunker shows storing data from the current scope in an accessible area when the controller's submit is clicked. From the new window it then parses the content from the opener into the window's scope for further processing.
http://plnkr.co/edit/OkKX5zxYVSoZ7w81WV8J?p=preview
You'll notice here too how to get an angular friendly way of calling the submission and the disabling of the button until ready.
Hope this helps.
How about to save your input data into a cookie on one page and then get it via JavaScript when you will open a new window?
I could prepare the code in jsFiddle, but seems like it does not import external resources at this moment. So I'll post it here:
page 1:
...
<form name="form" ng-controller="MyCtrl">
<label> <b> * Date: </b> </label> <input id="date" type="datetime-local" ng-model="date" name="date" onkeyup="changeButtonStatus()" onchange="changeButtonStatus()" required> </input>
<button id="btn" class="btn" >Submit</button>
</form>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#btn').click( function() {
var cookie_value = $('#inut_test').val();
/*cookie_value should be your json string*/
$.cookie("json_cookie", cookie_value, { path: '/' });
window.open("http://localhost/page2");
return false;
});
</script>
...
page 2:
...
<a id="see-cookie" href="#">
click me!!!
</a>
<script type="text/javascript" src="https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js"></script>
<script type="text/javascript">
$('#see-cookie').live('click', function() {
alert($.cookie('json_cookie'));
return false;
});
</script>
...
Do not forget about { path: '/' } cookie property to set it for all site and about including jQuery cookie library into your page.