FORM looks empty according to DOM-inspector - javascript

I have an issue with an web app im working on. The input-fields in the form is added by jQuery. My form looks like this in the HTML-editor:
<form id="profile" method="post" action="Profile/UpdateProfile">
<tr><td><b>Namn:</b></td><td><parameter name="Name" class="transform">#ViewBag.Name</parameter></td></tr>
<tr><td><b>Address:</b></td><td><parameter name="Address" class="transform">#ViewBag.Address</parameter></td></tr>
<tr><td><b>Postaddress:</b></td><td><parameter name="ZIP" class="transform">#ViewBag.ZIP</parameter></td></tr>
<tr><td><b>Personnummer:</b></td><td><parameter name="Pnumber" class="transform">#ViewBag.Pnumber</parameter></td></tr>
</form>
But it appears like this in the DOM-inspector:
<form id="profile" method="post" action="Profile/UpdateProfile"></form>
<tbody><tr><td><b>Namn:</b></td><td><parameter name="Name" class="transform">Anton Gildebrand</parameter></td></tr>
<tr><td><b>Address:</b></td><td><parameter name="Address" class="transform"></parameter></td></tr>
<tr><td><b>Postaddress:</b></td><td><parameter name="ZIP" class="transform">0</parameter></td></tr>
<tr><td><b>Personnummer:</b></td><td><parameter name="Pnumber" class="transform"></parameter></td></tr>
</tbody>
It may look weird that i have no inputs, but when the user presses an edit-button, the "parameter"-tag transforms into textinputs using this javascript:
$('#' + id + ' .transform').each(function (index) {
var val = $(this).html();
$(this).html('');
var tag = $(this).parent().html();
var newTag = tag.replace('<parameter', '<input type="text" value="' + val + '"');
newTag = newTag.replace('</parameter', '</input');
$(this).parent().html(newTag);
});
As you can see the "parameter"-tags isn't wrapped by the form in the DOM-inspector, and nothing is posted (i debugged using Fiddler) to the server. How do i solve it?

Wrap the form around the entire table.
You can't put forms inside a table element but outside a table cell. The result you see if the browser trying to perform error recovery. It is usually a good idea to make use of a validator (although you need to run it on the markup you intend to generate if you are generating it using JS).
(Also, use css for layout and use label elements instead of bold elements).

Related

Create a single search box which searches two different sites using javascript

I've made multiple search boxes that search external dictionary sites. Due to the site search syntax, I've had to use JavaScript to construct a url from the text box input. This code works perfectly fine:
function prepare_link_glosbe() {
var url_param_gl = document.getElementById('url_param_gl');
var target_link_gl = document.getElementById('target_link_gl');
if ( ! url_param_gl.value ) {
return false;
}
target_link_gl.href = "https://nb.glosbe.com/en/nb"
target_link_gl.href = target_link_gl.href + '/' + encodeURI(url_param_gl.value);
window.open(target_link_gl.href, '_blank')
}
function prepare_link_dict() {
var url_param_dict = document.getElementById('url_param_dict');
var target_link_dict = document.getElementById('target_link_dict');
if ( ! url_param_dict.value ) {
return false;
}
target_link_dict.href = "https://www.dict.com/engelsk-norsk"
target_link_dict.href = target_link_dict.href + '/' + encodeURI(url_param_dict.value);
window.open(target_link_dict.href, '_blank')
}
<!--Search Glosbe.com-->
<div style="border:0px solid black;padding:8px;width:60em;">
<table border="0" cellpadding="2">
<tr><td>
<input type="text" onfocus="this.value=''" value="Search glosbe.com" name="url_param_gl" id="url_param_gl" size="40"/>
<input type="button" onclick="prepare_link_glosbe()" value="Glosbe (en-no)" />
<a href="https://nb.glosbe.com/en/nb" id="target_link_gl" target="_blank" ></a>
</td></tr></table></div>
<!--Search Dict.com-->
<div style="border:0px solid black;padding:8px;width:60em;">
<table border="0" cellpadding="2">
<tr><td>
<input type="text" onfocus="this.value=''" value="Search dict.com" name="url_param_dict" id="url_param_dict" size="40"/>
<input type="button" onclick="prepare_link_dict()" value="Dict (en-no)" />
<a href="https://www.dict.com/engelsk-norsk" id="target_link_dict" target="_blank" ></a>
</td></tr></table></div>
However, I wish to search both sites using a single input box. I've tried different approaches, including addEventListener, but I'm not fluent enough in either HTML or JavaScript to achieve it. Can anyone point me in the right direction?
First of all, some things that will make your life easier in the long run:
You don't need this.value='', just use the placeholder attribute - it's well supported.
Don't use <table> to create a layout.
Don't use attributes to assign JS event handlers. (so no onclick=)
And now, how to use just one text field for both websites - just remove the second field and move the button somewhere else. Here's an example:
// This is our search input field.
const searchValue = document.getElementById('search_value');
// Here I'm looking for all search buttons and iterating over them
// with for ... of, querySelectorAll accepts valid CSS selectors.
for (let button of document.querySelectorAll('.search_button')) {
// Getting the data-url attribute value from the button.
const url = button.dataset.url;
// Adding a click event handler, instead of relying on onclick=''
button.addEventListener('click', function () {
// Quick string replace...
const targetURL = button.dataset.url.replace('%s', encodeURI(searchValue.value));
// ...and here we open the new tab.
window.open(targetURL, '_blank');
});
}
<div>
<input type="text" placeholder="Search..." id="search_value" />
<button class="search_button" data-url="https://nb.glosbe.com/en/nb/%s">Glosbe (en-no)</button>
<button class="search_button" data-url="https://www.dict.com/engelsk-norsk/%s">Dict (en-no)</button>
</div>
Here's the explanation:
I'm using the HTML data-* attributes (accessible in JS via element.dataset.*) to store the URL, %s is being used as a placeholder for the search value and will be later replaced with the .replace function.
Instead of manually assigning IDs to buttons I've declared a class - this allows you to extend the application infinitely.
I've merged the input fields into just one and read its value in the button event handler.
I've replaced your this.value='' hack with a proper placeholder.
I've removed the table layout, if you wish to add a nicer layout or styling I would suggest to learn more about CSS - also: don't use HTML attributes to style elements (except for class and style). Avoid using ID selectors in CSS as well (it's fine in JS, but in CSS it can cause issues when it comes to importance). Also, you should avoid the style attribute anyway - it will take precedence over most CSS rules except for the rules with !important and causes code duplication.

How can I apply a dynamic mask in an dynamic form?

I have a problem with my dynamic form. This input is:
<input type="text" class="form-control" placeholder="EX: (XX)-XXXX-XXXX" name="phone[]" id="phone">
This input have a mask
$('#phone').mask('(00)-0000-00000');
Everything works fine, but when I add a button who append a new input after the first the .mask filter doesn't work to the new .
How can I apply a dynamic mask in an dynamic form?
The .append function is:
$('#plusPhone').click(function(){
$('#appendPhone').append("<div class=\"row\"><div class=\"col-md-6\"><div class=\"form-group\"><label class=\"control-label col-md-3\">Phone</label><div class=\"col-md-9\"><input type=\"text\" class=\"form-control\" placeholder=\"EX: (XX)-XXXX-XXXX\" name=\"phone[]\" id=\"phone\"></div></div></div></div>"); });
You will have to add it dynamically just like this.
This is an untested code but the idea remains the same.
$('#plusPhone').click(function(){
$('#appendPhone').append("<div class=\"row\"><div class=\"col-md-6\"><div class=\"form-group\"><label class=\"control-label col-md-3\">Phone</label><div class=\"col-md-9\"><input type=\"text\" class=\"form-control\" placeholder=\"EX: (XX)-XXXX-XXXX\" name=\"phone[]\" id=\"phone\"></div></div></div></div>");
var code = "<script>$('#telefone').mask('(00)-0000-00000');</scr"+"ipt>";
$('#appendPhone').append($(code)[0]);
)};
Here is an example of how to execute js by appending it dynamically in htmls - enter link description here
This way you can append the code snippet to dynamically created htmls. Hope it helps
Pamio is on the right track. But appending the script to the page doesn't seem to work(?).
The following works for me:
$('#plusPhone').click(function(){
var HTML = 'this contains an input field with the class you want to mask';
jQuery('#element-you-want-to-append-to').append(HTML);
jQuery('.class-you-want-masked').mask('99-99-9999');
//Just call the mask AFTER appending the input, and it should be applied.
)};

JQuery: Append/After difficulties

I have a simple input line and want to append whatever has been entered each time somebody pushes the OK button. Sounds simple so far, still I am unable to get it working
HTML:
<p>
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<p id="status">Ok</p>
<br>
JQuery:
$(document).ready(function(){
$('#status').on('click', function(){
var input = $('input[name=todo]').val();
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').after('#status');
});
});
I also tried my luck with append or appendTo, but both times unsuccessfully.
Just in case here is the JSFiddle: http://jsfiddle.net/NRWzE/
.after() works, but you need to set it up correctly, according to documentation it should be:
.after( content [, content ] )
So the right way is:
$("#status").after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
Try use jquery insertAfter:
$(document).ready(function () {
$('#status').on('click', function () {
var input = $('input[name=todo]').val();
$('<br><b id="taskz">' + input + '</b> - <b id="statusz">Ok</b>').insertAfter('#status');
});
});
It looks like you meant to use:
$('#status').after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
(see after docs)
or, alternatively insertAfter:
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').insertAfter('#status');
Try this:
$('#status').click(function(){
var input = $('input[name=todo]').val();
$('#status').append('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
});
There are a few things going on, but the big thing is that you need to research more how after, append and appendTo work. Here's the basic syntax difference in the methods that share a name but one has To on the end:
Newcontent.appendTo(existingElement) returns newElements.
existingElement.append(newContent) returns existingElement.
Additionally, after puts the new element as a sibling of the reference element, whereas append puts the new element as a child. This is an important difference.
So, try this script then:
var taskid = 1;
$('#valueform').on('submit', function(){
var input = $('#todo').val();
$('<br><span id="task' + taskid.toString() + '">' + input
+ '</span> - <span id="status' + taskid.toString()
+ '">Ok</span>').appendTo('#status');
taskid += 1;
$('#todo').focus().select();
return false;
});
$('#todo').focus().select();
See a Live Demo at JSFiddle
Here's the supporting HTML:
<form id="valueform">
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<input type="submit" value="OK" id="okbutton">
</form>
<p id="status"></p>
There are some other concerns:
I recommend you study which HTML elements are allowed within which HTML elements.
Instead of putting a <b> tag on each item, use CSS. Additionally, if there is semantic importance for the bolding, then use <strong> instead. <b> also should probably not take an id because it is a presentation tag, not a content tag. When thinking of presentation vs. semantics, one must consider screen readers or browsers that cannot render bold text--in that case, <strong> will allow them to emphasize the text in another way if needed.
Get familiar with the jQuery documentation. Careful reading of what exactly each function does, the object it works on, the parameters expected, and the values returned will enable you to get past barriers in the future without having to ask here.
It looked to me like you wanted to put the new content inside of the #status paragraph, not after it. So I wrote my script that way. If you put it after the way you wrote it, then the most recent status will be on top--but then you have non block-level content (starting with your <br>) outside of any block-level element. So you should be appending <p> elements, or you should put your content inside the existing <p>.
Note: I added a form and made the button type submit instead of button to get easy Enter-key handling. It doesn't have to be this way.

Content added to innerHTML in chrome extensions gets modified

I have this JS code which adds some HTML inside a tbody:
thestring='<tr><td><input type="text" name="entry-'+s+'-api" value="'+getItem('entry-'+s+'-api')+' /></td><td><input type="text" name="entry-'+s+'-talk" value="'+getItem('entry-'+s+'-talk')+' /></td><td><input type="text" name="entry-'+s+'-url" value="'+getItem('entry-'+s+'-url')+' /></td></tr>';
document.getElementById('table').innerHTML+=thestring;
Bit long line, I know...
So when I run it, thestring is evaluated, correctly, to this:
<input type="text" name="entry-0-api" value="http%3A%2F%2Flego.wikia.com%2Fapi.php /><<input type="text" name="entry-0-talk" value="User_talk%3AUltrasonicNXT /><input type="text" name="entry-0-url" value="http%3A%2F%2Flego.wikia.com%2Fwiki%2FUser_talk%3AUltrasonicNXT />
However, this is the content that gets added:
<tr><td></td></tr>
So where did the rest go?
This is the relevent HTML:
<form action="change.js" method="GET">
<table>
<tbody id="table">
</tbody>
</table>
</form>
value="'+getItem('entry-'+s+'-api')+' />
Incorrect markup. No closing quote on attribute value. Chrome is doing its best to clean up the mistake.
But, in any case, you shouldn't be building markup strings this way. If there are any HTML-special characters in the getItem value, then they'll be able to leak into markup. If any of that content comes from an untrusted third-party, this HTML injection is not only a bug but a security hole.
document.getElementById('table').innerHTML+=thestring;
Never do this. This converts the entire current DOM of the table into HTML markup, adds to that string, and parses it all back in into new objects, replacing the old ones. This is slow and loses any information that doesn't serialise to HTML (such as event handlers or form field values).
It is much more reliable to alter the document's live DOM nodes directly than to mess about with HTML markup. This fixes both problems. eg.:
var row= document.getElementById('table').insertRow(-1);
['api', 'talk', 'url'].forEach(function(prop) {
var name= 'entry-'+s+'-'+prop;
var input= document.createElement('input');
input.type= 'text';
input.name= name;
input.value= getItem(name);
row.insertCell(-1).appendChild(input);
});
<input type="text" name="entry-0-api" value="http%3A%2F%2Flego.wikia.com%2Fapi.php />< is not correct. You're missing the <tr><td> (which is either a symptom or an oversight) but you also have an unclosed value attribute (appears to be the cause) and an extra < (which again looks like a symptom as it's inconsistent). The malformed data will cause some issues.

How can I create a dynamic form using jQuery

How can I create a dynamic form using jQuery. For example if I have to repeat a block of html for 3 times and show them one by one and also how can I fetch the value of this dynamic form value.
<div>
<div>Name: <input type="text" id="name"></div>
<div>Address: <input type="text" id="address"></div>
</div>
To insert that HTML into a form 3 times, you could simply perform it in a loop.
HTML:
<form id="myForm"></form>
jQuery:
$(function() {
var $form = $('#myForm'); // Grab a reference to the form
// Append your HTML, updating the ID attributes to keep HTML valid
for(var i = 1; i <= 3; i++) {
$form.append('<div><div>Name: <input type="text" id="name' + i + '"></div><div>Address: <input type="text" id="address' + i + '"></div></div>')
}
});
As far as fetching values, how you go about it would depend on your intent. jQuery can serialize the entire form, or you can select individual input values.
.append() - http://api.jquery.com/append/
This is a pretty broad question and feels a lot like 'do my work' as opposed to 'help me solve this problem.' That being said, a generic question begets an generic answer.
You can add new address rows by using the append() method and bind that to either the current row's blur - although that seems messy, or a set of +/- buttons that allow you to add and remove rows from your form. If you're processing the form with PHP on the server side, you can name the fields like this:
<input type='text' name='address[]' />
and php will create an array in $_POST['address'] containing all the values.

Categories

Resources