I have this text box in HTML:
<script src="../js/writeTo.js"></script>
<form>
<div class="post-title">
<input type="text" placeholder="Post Title">
</div>
<div class="post-content">
<textarea type="text" placeholder="Post Content"></textarea>
</div>
<button type="submit" class="submit">Submit</button>
</form>
and my js file called writeTo.js contains this code:
var url = "https://blog-posts.firebaseio.com/";
var firebaseRef = new Firebase(url);
function funct1()
{
var title = $('#post-title').val();
var post = $('#post-content').val();
var date = Date();
firebaseRef.set({Title: +title, Content: +post, Date: +Date()});
}
submit.onclick = funct1();
When I type something in my text box and click submit, I look at my Firebase and there is no new data (I'm also new to using Firebase).
It does not work, can anyone see the problem? (There are probably a few, I am new to JavaScript)
There are a few problems with your script. I've solved them in this jsfiddle, but will also explain below.
Getting the text content of your inputs
Your HTML for the inputs looks like this:
<div class="post-title">
<input type="text" placeholder="Post Title">
</div>
The JavaScript you use to read the value is:
var title = $('#post-title').val();
If you read the documentation for val, you'll see that it is meant to be invoked on the input element itself. You are invoking it on the wrapping div.
The simplest change is to get the value like this:
var title = $('#post-title').text();
Associating the handler with the form
You hook up your event handler with the form like this:
submit.onclick = funct1();
Unfortunately this will not work as you expect it to.
What is does is:
Invoke funct1
Assign the return value of funct1 to onclick
What you instead want to do is:
submit.onclick = funct1;
So this will assign funct1 to onclick.
You might want to read up on more modern approaches of assigning event handlers btw.
Passing the values to Firebase
Your code for passing the values to Firebase seems a bit off. Use this instead
firebaseRef.set({Title: title, Content: post, Date: date});
Cancel the regular browser handling of the form submit
The browser normally handles clicks on a form's submit button by posting the form's values to a URL.
But in your application you are handling this yourself, so you should tell the browser to ignore the submit.
You can do this by returning false from your function:
return false;
Note that this will give the following warning in Chrome:
event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
So you should indeed consider using event.preventDefault() instead of returning false. See the total code below for how to do that.
Complete code
var url = "https://blog-posts.firebaseio.com/";
var firebaseRef = new Firebase(url);
function funct1(evt)
{
var title = $('#post-title').text();
var post = $('#post-content').text();
var date = Date();
firebaseRef.set({Title: title, Content: post, Date: date});
evt.preventDefault();
}
var submit = document.getElementsByTagName('button')[0];
submit.onclick = funct1;
Adding a new post, instead of overwriting the existing one
Your code will now replace the blog post that lives at your Firebase. I imagine that you'll probably prefer to add a new post, when pressing the submit button.
To accomplish this, you'll need to call Firebase's push function. Firebase has some great documentation on managing lists.
The gist of it is this though:
var postRef = firebaseRef.push(); // create a new post
postRef.set({Title: title, Content: post, Date: date});
So you create a new post and then set your values on that, instead of on the top-level Firebase ref.
Related
I am very new to html, css, and javascript so please go easy on me. I am working on an activity that requests: Register the updateCount event handler to handle input changes for the textarea tag. Note: The function counts the number of characters in the textarea.
The Javascript so far is as follows -
var textareaElement = document.getElementById("userName");
function updateCount(event) {
document.getElementById("stringLength").innerHTML = event.target.value.length;
}
// Write code here
I have absolutely no idea what it is asking of me for this problem. Both online resources and textbooks have not been very helpful.
The HTML cannot be changed in any way, forcing me to solve it with just changes the the javascript.
The HTML is as follows -
<label for="userName">User name:</label>
<textarea id="userName" cols="40" rows="3"></textarea><br>
<p id="stringLength">0</p>
Any help would be much appreciated, I'm just trying to learn.
Try this. Add onkeyup event on the <textarea> tag then replace event.target to textareaElement to get the value
var textareaElement = document.getElementById("userName");
function updateCount() {
document.getElementById("stringLength").innerHTML = textareaElement.value.length;
}
<label for="userName">User name:</label>
<textarea id="userName" onkeyup="updateCount()" cols="40" rows="3"></textarea><br>
<p id="stringLength">0</p>
When you have a reference to a DOM node (e.g, <textarea>), you can bind event handlers for the various events that it supports. In this case, we consult the HTMLTextAreaElement docs and learn that the following piece of JS would give the text length
const textarea = document.getElementById('userName');
const length = textarea.value.length; // textarea.textLength;
Then, we will consult the docs to determine that it is the input event that we want to bind to.
textarea.addEventListener('input', updateCount);
Your updateCount gets as its input the input event that also contains a reference to the event target, which is the textarea.
var textareaElement = document.getElementById("userName");
function textSize(event) {
document.getElementById("stringLength").innerHTML = event.target.value.length;
}
textareaElement.addEventListener("input", function(event){
document.getElementById("stringLength").innerHTML = event.target.value.length;
});
I know the post is old but I just had to figure this one out for myself so for anyone else that has trouble in the future here is the line you need.
textareaElement.addEventListener("blur", updateCount);
I am trying to update some old code that works correctly on all versions of IE except IE11. When an anchor tag is clicked a javascript function is run. The function . All that the function does is that it gets certain values from the DOM and then submits a form using the post action.
I understand that IE11 submit does not work if the input element does not have a name. Here, the submit is done by clicking on an anchor tag- I tried adding a name and id to the anchor tag but it is still not working.
Any idea on how to get it to work. Following is the anchor tag.
<a class="nohigh" href="javascript:getClassDetails('<%=Id%>');">
Following is the javascript function:
function getClassDetails(a){
var classId = document.getElementById(classIdRow ).value;
var courseId = document.getElementById(courseIdRow).value;
document.getElementById('val1').value = classId
document.getElementById('val2').value = courseId
document.getElementById('clasCourseForm').submit();
}
The function that you want should be:
function getClassDetails(a){
var classId = document.getElementById(classIdRow).value; // assuming classIdRow is defined
var courseId = document.getElementById(courseIdRow).value; // assuming courseIdRow is defined
document.getElementById('val1').value = classId;
document.getElementById('val2').value = courseId;
document.getElementById('clasCourseForm').submit();
}
That's at least assuming that all the JavaScript you have up there ^ is verbatim.
[edit: removed the original answer, as the question has been changed to correct the syntax]
In addition, the JS code has other weirdness, in that the function is accepting a parameter (a) but never uses it within the function. There's almost certainly some kind of logic mistake involved there which you'll want to look into.
fixed it - by adding both a name and id to the form.
I'm trying to make a dynamic form with AngularJS and JavaScript. The objective is to add how many inputs the user need and transform all those inputs in AngularJS variables that print it on body. So I got that code:
$(function(){
var number = 1;
$('a.add').click(function(e){
e.preventDefault();
$('#this_div_contains_settings').append('<input type="text" name="example'+number+'" ng-model="example'+number+'" placeholder="Anything">');
number++;
});
$('#this_div_contains_settings').on('click','a.design_button', function(e){
e.preventDefault();
$(this).parent().remove();
});
});
This function add a INPUT on my DIV with the different ng-model every time it run.
The problem is, it just work's if the {{example1}} is already on my BODY, if I add it later with another function, it just doesn't work.
I'm new with AngularJS, so I didn't understand if I need to "refresh" the AngularJS everytime I add new variable or something like that.
Any help will be appreciated :)
Using jQuery is the wrong way to solve this problem. Instead, create an array inside of your controller that will hold the models for all of these inputs.
Depending on how you define/create your controllers, $scope may be replaced with this
$scope.examples = [];
Next, create a function that will add a new example to the array:
$scope.addExample = function () {
$scope.examples.push("");
}
Now, in your template, create the inputs using an ng-repeat:
<div id="this_div_contains_settings">
<input ng-repeat="example in examples" type="text" name="example" ng-model="example" placeholder="Anything">
</div>
and have your "add" button call your addExample function on click:
<a class="add" ng-click="addExample()">Add Example</a>
Finally, remove all of the code that was included in your question.
And for your .design_button that removes all the examples, that's easy too:
<a class="design_button" ng-click="examples = []">remove all examples!</a>
by that same concept, you could even remove the need for the addExample function, however i tend to keep logic in the controller (well, actually in the services, but that's another topic) anyway rather than putting it in the template.
I am trying unsuccessfully to get a handle on the text input into a textarea which is contained inside an xe:dialog. The xe:dialog "pops up" after a button on the XPage is pressed. Here is my code:
<xe:dialog id="InputDialog5">
<xe:this.title>"Input Dialog</xe:this.title>
<xp:panel>
<xp:inputTextarea id="InputTextBox5" value="#{document1.InputTextBox5}"
cols="60" rows="4"></xp:inputTextarea>
</xp:panel>
<xe:dialogButtonBar id="dialogButtonBar15">
<xp:button value="OK" id="button37">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete" immediate="true">
<xp:this.action><![CDATA[#{javascript:
var request = facesContext.getExternalContext().getRequest();
var header = request.getHeader("Cookie");
var inputVal = #Middle(header,"InputTextBox5=",";")
setJobReferenceStatus(40,inputVal);
var redirect = "window.location='"+applicationScope.get("redirect")+"'";
facesContext.getViewRoot().postScript(redirect);}]]></xp:this.action>
<xp:this.script><![CDATA[
var inputvalue = document.getElementById("InputTextBox5").value;
alert("inputvalue = " + inputvalue);
dojo.cookie("InputTextBox5", inputvalue, { expires: 1 });
]]></xp:this.script>
</xp:eventHandler>
</xp:button>
</xe:dialogButtonBar>
</xe:dialog>
My idea is to get the value of the textarea, add it to a dojo cookie, retrieve the cookie value using SSJS and then pass the value to an SSJS function. However the code fails already at the stage of getting the textarea value. The line "alert("inputvalue = " + inputvalue);" is not executed and the dialog box remains "frozen". Any idea on how I can resolve this problem?
In order to get a handle on the text field from client side Javascript you have to know the XPages generated client id. So do this instead to calculate the id inside your CSJS:
<xp:this.script><![CDATA[
var inputvalue = document.getElementById("#{id:InputTextBox5}").value;
alert("inputvalue = " + inputvalue);
dojo.cookie("InputTextBox5", inputvalue, { expires: 1 });
]]></xp:this.script>
at a quick look I can already see two major obstacles:
a) document.getElementById(..) probably won't do (in fact I never really tried). I use XSP.getElementById(..) or dojo.byId(..) instead
b) your textarea will never ever have the same id at runtime that it has at design time. Just use your browser's sourcecode viewer, and you will see what I mean. Therefor we have to instructions to calculate the resulting ids for us like this:
dojo.byId("#{id:InputTextBox5}")
this then will be translated into the client object's final id so that your client side script code can find it.
Didn't look at the rest of your code, so I can't tell if there are more potential problems in there
I have a problem with dynamically including an object-tag in my html.
We have a external service which we call to get some html-fragment, it includes an object-tag, a script and a simple html-form. I take that content and add it to a div in my page and then try to execute the script that uses the included object. When i debug using Firebug I can see that the code is correctly inserted in the page but the script gets an error when it tries to access the object. It seems to me that the object isn’t initialized. Let me show you some code to exemplify what I mean.
getFragment makes an ajax call using jQuery to get the content.
var htmlSnippet = RequestModule.getFragment( dto );
$('#plugin').html( htmlSnippet ).hide();
The included content in plugin-div looks like this
<div id="plugin" style="display: none; ">
Browser:
Chrome
<object name="signer" id="signer" type="application/x-personal-signer2"></object>
<form method="POST" name="signerData" action="#success">
<input name="nonce" value="ASyhs..." type="hidden">
<input name="signature" value="" type="hidden">
<input name="encodedTbs" value="U2l..." type="hidden">
<input name="provider" value="nexus-personal_4X" type="hidden">
<input type="submit" onclick="doSign()" value="Sign">
</form>
</div>
The javascript that tries to use the “signer” object looks like this:
function doSign(){
var signer2 = document.getElementById("signer");
retVal = signer2.SetParam('TextToBeSigned', 'some value...');
... and then some more
}
It’s when i call the signer2.SetParam method that I get an error saying
Object #<an HTMLObjectElement> has no method 'SetParam'
But when I use the original page where the content is loaded when the page loads the script works so I know that the ‘SetParam’ method exists on the object and that the script works. But somehow it doesn’t work when I dynamically add it to the page afterwards.
I’ve Googled this a lot the last couple of days with no luck.
Does anyone have any idea on how to get this to work?
Best regards,
Henrik
First of all Object tag is not fully supported in all browsers (Source)
Next, from my experience, jQuery (which heavily relies on document.createDocumentFragment) sometimes fails to attach/trigger events on dynamically created/cloned DOM nodes, which could explain why your object failed to initialize.
That said, to try and fix your problem, I suggest using native document.createElement and document.appendChild methods instead of jQuery.html. You can try document.innerHTML but if that fails, you can always go with the ones I mentioned earlier.
My suggestion is to either alter your service to replace:
<script type="text/javascript">
function addElement(parentid, tag, attributes) {
var el = document.createElement(tag);
// Add attributes
if (typeof attributes != 'undefined') {
for (var a in attributes) {
el.setAttribute(a, attributes[a]);
}
}
// Append element to parent
document.getElementById(parentid).appendChild(el);
}
addElement('plugin', 'object', {name:"signer",id:"signer",type:"application/x-personal-signer2"});
</script>
OR if you cannot change the content that is returned by the service, run this after you include the content onto your page:
<script type="text/javascript">
/*
* Goes through al the object tags in the element with the containerid id
* and tries to re-create them using the DOM builtin methods
*/
function reattachObjectTags(containerid) {
jQuery('#'+containerid+' object').each(function(){
var attrs = {}, el = this;
// We're insterested in preserving all the attributes
var saved_attrs = {}, attr;
for(var i=0; i < el.attributes.length; i++) {
attr = el.attributes.item(i);
if(attr.specified) {
saved_attrs[attr.nodeName]=attr.nodeValue;
}
}
this.parentNode.removeChild(this);
var new_element = document.createElement('object');
for (var a in saved_attrs) {
new_element.setAttribute(a,saved_attrs[a]);
}
document.getElementById(containerid).appendChild(new_element);
});
}
// Do your stuff
var htmlSnippet = RequestModule.getFragment( dto );
$('#plugin').html( htmlSnippet ).hide();
// reattach all the object elements in #plugin
reattachObjectTags('plugin');
</script>
THIS IS ALL UNTESTED -
I typed this off the top of my mind, since I don't have the means to fire up IE and test this.
For a jQuery solution, I think this should work:
$("input:submit").click(function(){
$("#signer").append('<param name="TextToBeSigned" value="some value ...">');
... and then some more
});
Might want to give the submit button a class or an id and use that as a selector, if you have multiple forms on that page though.
Hope this helps.
I've set up a test script here: https://dl.dropbox.com/u/74874/test_scripts/object.html
If you open up Firebug/Web Inspector, you'll see that the SetParam method is in-fact, not defined. I don't know what it's supposed to do, but it's not defined in either case. If you're trying to add <param> tags to your embed, you could use the DOM API to do that. There is some code in the test script that does that, but I'll paste it here anyway:
var obj_signer = document.getElementById('signer');
var obj_p = document.createElement('param');
obj_p.id = "myp2";
obj_p.name = "TextToBeSigned";
obj_p.value = "some value ...";
obj_p.setAttribute('valueType', 'ref');
obj_signer.appendChild(e);
Or be faster using jQuery:
$("#signer").append("<param id='myp2' name='TextToBeSigned' value='some value ...' valueType='ref'></param>");