Javascript / Jquery .html() replaces only once - javascript

Hi I am trying to achieve the following:
1) User clicks on file input button, textfield gets replaced with the name of the file
2) User changes the value of the text field, the file contents are erased..
This works fine. However if the user does 1) after he does 2) the values are not showing up in the text field anymore..
This is on Backbone with coffee script..
events:
'change #soundfile': 'soundReceived'
'change #soundtrack': 'linkInput'
soundReceived: (event) ->
$('#soundtrack').html($('#soundfile').val().replace("C:\\fakepath\\", ''))
#
linkInput:(event) ->
match = $('#soundtrack').val().match('http://')
if match
$('#soundfile').replaceWith($("#soundfile").clone());
console.log($('#soundfile').val())
else
console.log($('#soundfile').val())
$('#soundtrack').html($('#soundfile').val().replace("C:\\fakepath\\", ''))
#
Edit
<div id = "create_form" >
<form class="new_plot" name="create_form" id ="new_plot" data-remote="true" enctype="multipart/form-data">
<div id = "sound_gen">
<span>
<textarea class="input" id="soundtrack" name="name" rows="1" onClick="if(this.value == 'Soundtrack: upload mp3 file') { this.value = ''; }">Soundtrack: upload mp3 file</textarea>
</span>
<img id = "btn_upload" src ="/assets/upload_icon.png"></img>
<input name="soundtrack" type="file" id ="soundfile"/>
<span class ="generate">
<input class="blue_button btn_generate" name="commit" type="submit" value="create" id ="plot_subm"/>
</span>
</div>
</form>
</div>

You should be using val to change the value of a form element, not html, for example:
soundReceived: (event) ->
$('#soundtrack').val($('#soundfile').val().replace("C:\\fakepath\\", ''))
#
Trying to change the value of an <input type="file"> through a script is generally pointless (for hopefully obvious reasons) but you can try with .val(...) if you'd like.
Stripped down demo: http://jsfiddle.net/ambiguous/5n6aZ/
Also, you should probably be using a placeholder attribute instead of your onClick handler in your <textarea>.

This line:
$('#soundtrack').html($('#soundfile').val().replace("C:\\fakepath\\", ''))
Should be like this:
$('#soundtrack').html($('#soundfile').val(''))
So really it was 2 problems:
The only value you're allowed to send to a file input is an empty string
$.val() accepts a single parameter for value, it isn't set like a property
Hope this helps!

Related

Jquery insert span into input field

I'm building a simple tagging system for an text input field, here's what it looks like.
At the moment, the next tag is being added before the input field, but I'd like it to appear within the input field, so that if the users hits backsapce, it will delete the tag. If that makes sense. I'm not sure how to get the span to appear inside of the input field, here's the code:
<div id="formWrapper" class="ui-widget">
<form id="searchForm" action="#">
<fieldset>
<legend>Test search form</legend>
<span>Search</span>
<div id="searchBoxDiv" class="ui-helper-clearfix">
<button type="button" id="savedSearchButton">Test</button>
<input id="searchBox" type="text" autocomplete="false">
</div>
</fieldset>
</form>
</div>
function addSearchTerm(e, ui) {
var searchTerm = ui.item.value;
var span = $("<span>").text(searchTerm);
var a = $("<a>").addClass("remove").addClass("testclass").attr({
href: "javascript:",
title: "Remove " + searchTerm
}).text("x").appendTo(span);
span.insertBefore("#searchBox");
}
I've tried various combinations of insert, append but I don't seem to be able to get anything inside of the input, except text. I'm guessing I'll have to do something where the input field is within another , but I'm really not sure how.
Thanks

Adding input elements to the DOM using jQuery

I am programming a web application which accepts barcodes from a barcode reader in an input field. The user can enter as many barcodes that s/he wants to (i.e. there is no reason for a predefined limit). I have come up with a brute force method which creates a predefined number of hidden input fields and then reveals the next one in sequence as each barcode is entered. Here is the code to do this:
<form id="barcode1" name="barcode" method="Post" action="#">
<div class="container">
<label for="S1">Barcode 1 &nbsp </label>
<input id="S1" class="bcode" type="text" name="S1" onchange="packFunction()" autofocus/>
<label for="S2" hidden = "hidden">Barcode 2 &nbsp </label>
<input id="S2" class="bcode" type="text" hidden = "hidden" name="S2" onchange="packFunction()" />
<label for="S3" hidden = "hidden">Barcode 3 &nbsp </label>
<input id="S3" class="bcode" type="text" hidden = "hidden" name="S3" onchange="packFunction()" />
<label for="S4" hidden = "hidden">Barcode 4 &nbsp </label>
<input id="S4" class="bcode" type="text" hidden = "hidden" name="S4" onchange="packFunction()" />
<label for="S5" hidden = "hidden">Barcode 5 &nbsp </label>
<input id="S5" class="bcode" type="text" hidden = "hidden" name="S5" onchange="packFunction()" />
</div>
<div class="submit">
<p><input type="submit" name="Submit" value="Submit"></p>
</div>
</form>
<script>
$(function() {
$('#barcode1').find('.bcode').keypress(function(e){
// to prevent 'enter' from submitting the form
if ( e.which == 13 )
{
$(this).next('label').removeAttr('hidden')
$(this).next('label').next('.bcode').removeAttr('hidden').focus();
return false;
}
});
});
</script>
This seems to be an inelegant solution. It would seem to be better to create a new input field after each barcode has been entered. I have tried creating new input elements in the DOM using jQuery, and I can get the new input element to show. But it uses the onchange event, which detects changes in the original input field. How do I transfer focus and detect onchange in the newly created input field? Here is the code that I have played with to test out the idea:
<div>
<input type="text" id="barcode" class="original"/>
</div>
<div id="display">
<div>Placeholder text</div>
</div>
<script src="./Scripts/jquery-2.2.0.min.js"></script>
$(function () {
$('#barcode').on('change', function () {
$('#display').append('<input id='bcode' class='bcode' type='text' name='S1' autofocus/>')
});
});
</script>
Once I have these barcodes, I pack them into array which I then post them to a server-side script to run a mySQL query to retrieve data based on the barcodes, and then post that back to the client. So part of what I have to achieve is that each barcode that is entered into the different input fields need to be pushed into an array.
Is there an elegant way to accomplish the creation of input fields dynamically and then detecting changes in those to create yet more input fields?
The dynamic update you have tried out is all right. If you must push it into an array on submit you have to prevent default of form submit, serialize the form and then make an ajax request.
Heres an example:
$('form').on('submit',function(e){
e.preventDefault();
var formData = $(this).serializeArray();//check documentation https://api.jquery.com/serializeArray/ for more details
$.ajax({
type:'post',
url:<your url>//or you could do $('form').attr('action')
data:formData,
success:function(){}//etc
})
});
If you do not display the barcodes in the html you can skip the input fields and store the read barcodes in an array[]. Not everything that happens in javascript has to be displayed in the website (View) . i do not know what code you use to scan the barcode but you do not need the input-elements at all.
See the example on this site https://coderwall.com/p/s0i_xg/using-barcode-scanner-with-jquery
instead of console.log() the data from the barcode scanner can simply be saved in an array[] and be send from there.
If you want to create elements dynamcially see this thread: dynamically create element using jquery
The following code adds the p-element with the label "Hej" to the div "#contentl1"
`$("<p />", { text: "Hej" }).appendTo("#contentl1");`
UPDATE: I added some simple CSS to make each input field display on its own line.
Here's one strategy:
Listen for the enter/return key on the input box.
When the enter/return key is pressed (presumably after entering a barcode), create a new input box.
Stop listening for the enter key on the original input and start listening for it on the new input.
When a "submit all" button is pressed (or when tab is used to shift the focus from the most recent input to the "submit all" button and enter is pressed), then collect all the input values in an array.
$(function() {
var finishBarcode = function(evt) {
if (evt.which === 13) {
$(evt.target).off("keyup");
$("<input class='barcode' type='text'/>")
.appendTo("#barcodes")
.focus()
.on("keyup", finishBarcode);
}
};
var submitBarcodes = function(evt) {
var barcodesArr = $(".barcode").map(function() {
return $(this).val();
}).get();
$("#display").text("Entered Barcodes: " + barcodesArr);
};
var $focusedInput = $('.barcode').on("keyup", finishBarcode).focus();
var $button = $('#submitAll').on("click", submitBarcodes);
});
input.barcode {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Type barcode into input box</li>
<li>To enter barcode and allow new entry, press Return</li>
<li>To submit all barcodes, either press tab and then return or click Submit button</li>
</ul>
<div id="barcodes"><input type="text" class="barcode" /></div>
<div><button id="submitAll">Submit all barcodes</button></div>
<div id="display">Placeholder text</div>

Change the value of xforms element via javascript?

I was wondering if it's possible to change the value of an xforms element via javascript and then submit the form with that value?
what i have tried is change the text of an xforms:input when an <input type="file"> is triggered and it works, the thing is that when i submit the form, the xforms:input doesn't seem to apply the value
<div id="ubi" class="controls">
<xf:input ref="ubicacion"/>
<input class="input-file" id="fileadjunto" type="file" onchange="uploadfile()"/>
</div>
<script>
function uploadfile()
{{
var inp = document.getElementById('fileadjunto');
var name = inp.files.item(0).name;
var span1 = document.getElementById('ubi').getElementsByTagName('span')[0].getElementsByTagName('span')[0].getElementsByTagName('input')[0];
span1.value = name;
}};
</script>
why am i getting the spans and inputs? if you check the xforms:input element in the console you'll see that it's converted to
<span .....>
<span.....>
<input..../>
</span>
</span>

How do I replace part of the value of attributes for a set of elements in jQuery?

I am trying to replace a series of 'for' attributes of labels based on their current contents.
The application is using AJAX to add an item to an invoice without refreshing the page. Upon receiving notification of a successful item add, my script should replace all the labels in the form whose 'for' attribute ends with '-new' with the same attribute minus the '-new' and adding ('-' + itemValue), where itemValue is the item Id of the invoice item that was added.
I know how to select all the labels I want to change at once:
jQuery('label[for$=new]')
I know how to get their 'for' attribute:
jQuery('label[for$=new]').attr('for')
I tried the JavaScript replace method:
jQuery('label[for$=new]').attr('for').replace(/-new/,itemValue)
But that appears to select each label's 'for' attribute, replace the text, and pass the replaced text back (to nothing), since I don't know how to identify the labels that have the 'for' attribute I want to replace.
Here's some sample HTML:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF'];?>" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div id="InvoiceItem-new-1" class="InvoiceItem">
<label for="InvoiceItemNumber-new">New Invoice Item Number: </label>
<input id="InvoiceItemNumber-new" class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber-new">
<label for="InvoiceItemDescription-new">Item Description: </label>
<input id="InvoiceItemDescription-new" class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new">
<label for="InvoiceItemAmount-new">Item Amount: </label>
<input id="InvoiceItemAmount-new" class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new">
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
Once I get this to work, I'm going to replace all the ids for all the inputs. Same problem. I imagine the solution looks something like this:
jQuery('input[id$=new]').attr('id').replace(/-new/,itemValue)
I just cannot figure out the syntax for this at all.
No need to use .each() ... the .attr() method accepts a function as the second parameter that returns the new value to be used as replacement
jQuery('label[for$=new]').attr('for', function(index, currentValue){
return currentValue.replace(/-new/,'-' + itemValue);
});
If I may, why not just put the input tag inside the label tag? That way, you won't need a for attribute inside the label tag.
Next, a better way to accomplish what you're trying to do would be to use the invoice ID number as the ID for the surrounding div, and add a 'new` class for "new" invoice entries.
So your form would look something like this:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF']" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div class="InvoiceItem new">
<label>New Invoice Item Number: <input class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber"></label>
<label>Item Description: <input class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new"></label>
<label for="InvoiceItemAmount-new">Item Amount: <input class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new"></label>
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
You'll still have all the targetability you need to get the new invoice item field data, but now, you only have two things to do to convert from a "new" invoice row to an "existing" invoice item row: add an id attribute to the div and remove the new class, both of which jQuery will let you do quite easily.
Not sure I get the question, but something like:
var oldFor = $('label[for$=new]').attr('for');
var newFor = oldfor.replace(/-new/,itemValue);
$('label[for$=new]').attr('for', newFor);
.attr( attributeName, value )
attributeName = The name of the attribute to set.
value = A value to set for the attribute.
When selecting multiple elements, you will need to iterate:
$('label[for$=new]').each(function(index) {
$(this).attr('for', $(this).attr('for').replace(/-new/, '-' + itemValue));
});

Build URL from form fields with JavaScript or jQuery

I'm trying to create a URL builder form with JavaScript or jQuery.
Basically, it will take the value of the two form fields, add them to a preset URL and show it on a third field on submit.
The resulting URL might be http://example.com/index.php?variable1=12&variable2=56
Now, this isn't the "action" of the form and the application can't read a URL (to grab the variables), so it has to be done on the page.
The resulting URL will be shown in the field named "url".
Here's a sample of the form:
<form id="form1" name="form1" method="post" action="">
<p>
<label>Variable 1
<input type="text" name="variable1" id="variable1" />
</label>
</p>
<p>
<label>Variable 2
<input type="text" name="variable2" id="variable2" />
</label>
</p>
<p>
<label>URL
<input type="text" name="url" id="url" />
</label>
</p>
<p>
<input type="submit" name="button" id="button" value="Submit" />
</p>
</form>
jQuery has serialize which builds the query string values.
So if you want to do the entire form:
alert($("#form1").serialize());
If you want to do only a few fields, then just make the selector select those fields.
alert($("#variable1, #variable2").serialize());
Use something like...
var inputs = $('#form1').find('input[type=text]').not('#url');
var str = "http://www.base.url/path/file.ext?"
inputs.each(function (i, item) {
str += encodeURIComponent(item.name) + "=" + encodeURIComponent(item.value) + "&";
});
$('#url').val(str);
This will select all <input>s on in form1 with type='text', and concatenate them into a query string. See encodeURIComponent().
Orrrr.....you could just use .serialize(). Thank you, prodigitalson.
Something like the following should work:
var partFields = '#variable1,#variable2';
$(partFields).change(function(){
var url = 'static/URL/to/file.php?';
$('#url').val(url + $(partFields).serialize());
});
However, unless you want people to be able to override the URL, you might want to use a hidden field and a regular element for display and submission of the URL value in which case you'd have something like the following:
var partFields = '#variable1,#variable2';
$(partFields).change(function(){
var url = 'static/URL/to/file.php?';
var urlValue = url + $(partFields).serialize();
$('#url-display').text(urlValue); // Set the displaying element
$('#url').val(urlValue); // Set the hidden input value
});

Categories