We have a bootstrap select (Phasentyp) that is added dynamically via a template.
The template looks like this:
<div class="form-group">
<div class="form-row">
<div class="col-4">
<form-group asp-for="#projektphaseTemplate.PhasenTypId" asp-horizontal="true" asp-label-suffix=" *" data-none-selected-text required></form-group>
</div>
</div>
</div>
When adding the template, the select is processed via JavaScript:
// Process the bootstrap selects
projektphase.find('select').each(function(index, element) {
const el = $(element);
// Replace name
let newName = el.attr('name').replace(/projektphaseTemplate/, `Projekt.PPMProjektPhase[${newIndex}]`);
el.attr('name', newName);
// Replace ID
let newId = $(element).attr('id').replace(/projektphaseTemplate/, `Projekt_PPMProjektPhase_${newIndex}_`);
el.attr('id', newId);
// Remove all bootstrap-select DOM Stuff for prune select-elements
el.closest('.bootstrap-select').replaceWith($(element));
// Reinitialize bootstrap-select
el.selectpicker({
noneSelectedText: ''
});
});
But unfortunately, when saving with the empty option selected, the validation doesn't work.
What is "funny" is, that when I fill out the other required fields and save again, then the validation seems to trigger but with the wrong message:
The HTML looks like this:
What am I doing wrong, that the validation isn't triggered by the first save?
Thanks in advance
You have to reapply jquery's validation to your element, after you changed the name of it.
See here: jQuery - How to dynamically add a validation rule
Related
I have two html divs, each having a bunch of input fields. I also have an angular controller that gets the data entered in the input fields and checks if they are valid (ie: email, passwords match, etc). What I'm trying to do is hide the first div and show the second one once the controller says that the text entered in the first div is valid. Here is what the html looks like:
<div id = "stageOne">
<!-- whole bunch of inputs here -->
</div>
<a class = "btn" id = "stageOneDone" ng-click = "checkFields(true)">Continue</a>
<!-- First stage ends here-->
<div align = "center" id = "stageTwo" style = "display: none">
<!-- whole bunch of inputs here -->
</div>
<script>
$(function(){
$('#stageOneDone').click(function(){
//var completedIncorrectly = something
if(!completedIncorrectly){
$('#stageOne').hide();
$('#stageTwo').show();
}
})
});
</script>
The function checkFields() expects the value true when it should check the values of the first div and false for the second div. What I can't figure out how to do is get the return value of the function and use it in jquery.
EDIT: If you're thinking why not just show/hide the divs using angular, I want to use jquery's animations.
Fixed this problem by just writing all the jquery in the controller.
You can set variable inside controller, like $scope.step = 'one';
<div ng-show="step='one'">first step</div>
<div ng-show="step='second'">second step</div>
...
You don't need jQuery to do this.
I have a dynamic page that can have a lot of input[type="file"] fields. I need to change the label of every input once a file is selected.
So, for each input, if:
Empty: text = "upload";
File selected: text = name of file.
Here is a sample of HTML:
<label for="upload-qm1">
<span class="button">upload</span>
<input id="upload-qm1" type="file" accept=".pdf, .doc">
</label>
I know how to do this for a single input, using this code:
$('label[for="upload-qm1"] span').text($(this).val());
However, I don't know how many input fields I will have on my page. I tried something like this:
$(this).parent('label').find('span').text($(this).val());
but unfortunately it doesn't work. Any help on how I can get a method for changing all input fields?
You can use DOM traversal to find the span related to the input which was changed. Try this:
$('input:file').change(function() {
$(this).prev('span').text($(this).val());
})
Working example
The most of the code you tried ist corret.
The problem is that you have set a parameter for the parent() function.
Try something like this:
$(this).parent('label').find('span').text($(this).val());
Also make sure that $(this) is the input field not the label itself,
if you click on the label $(this) is the label.
$('input[type="file"]').on('change', function() {
id = $(this).attr('id');
console.log("change event")
var file = $('#'+id).val().split('\\').pop();
if(file!='') {
$('label[for="'+id+'"] span').text(file)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="upload-qm1">
<span class="button">upload</span>
<input id="upload-qm1" type="file" accept=".pdf, .doc">
</label>
This is the main form:
<div>
<form method="post" class="register" id="wiz-config">
<!-- HTML -->
<input type="radio" value="187" name="group-1" id="product-187" class="aselector" >
<input type="radio" value="188" name="group-1" id="product-188" class="aselector" >
<!-- HTML -->
<!-- Other ajax fields -->
</form>
</div>
Other ajax fields are loaded via ajax.
The problem is that if I use
jQuery( document ).ready(function() {
var str = jQuery( "#wiz-config" ).serialize();
console.log(str);
});
it returns is "empty". Why?
You've just forgotten to put the selector # :
$( "#wiz-config" ).serialize();
Your jQuery selection is wrong. You need # because you are trying to select by the Id.
$("#wiz-config" ).serialize();
ID Selector (“#id”) : Selects a single element with the given id
attribute.
Or if you have only one form in your page, you may try this as well to get the form
var _form = $("form");
console.log(_form);
var serializedVersion = _form.serialize();
EDIT : As per the comment, you are not getting the dynamically added form elements. The only reason i can think of is, You might not be giving the name attribute and it's value to these dynamically added form elements. serialize method will serialize only those elements with a valid name attribute.
The below should work without any problems.
$(function(){
var newItems="<input name='place' type='text' />";
$("#wiz-config").append(newItems);
});
Here is a working sample.
You are calling an element not an ID.
$("wiz-config").serialize();
Is looking for an element, such as p, div, etc.
To call an item by ID, you need to add a leading #:
$("#wiz-config").serialize();
I have an array of Bootstrap Selectpickers for filtering results from a database. I need a way of resetting all the selectpickers to 'Nothing Selected', this is my code:
HTML
<div class="row">
<div class="col-md-3">
<label>By Group</label>
<select id="groups" name="group" class="form-control selectpicker" multiple></select>
</div>
<div class="col-md-3">
etc...
</div>
</div>
JS
ajax_fetch('build_group_options', {groupno:groupno}).done(function(html) {
//var html is a list of options in html format
$('#groups').html(html).find('option[value=""]').remove();
//refresh the selectpicker to make sure options are registered in the picker
$('.selectpicker').selectpicker('refresh');
});
Try to reset all the pickers:
$('#reset_filters').click(function() {
$('.selectpicker').selectpicker('deselectAll');
$('.selectpicker').selectpicker('render');
$('.selectpicker').selectpicker('refresh');
$(this).closest('form').find('.selectpicker').each(function() {
$(this).selectpicker('render');
});
});
As you can see I have tried all the functions to reset but to no avail so am obviously doing some wrong further up the logic.
I got solution from following code.Try it
$("#listID").val('').trigger('change');
And also you can try this
$("#listID").val('').selectpicker('refresh');
Maybe it's a little late, but maybe it'll help someone someday. For me the solution was this:
$("#listID").val([]).selectpicker('refresh');
I had the multiselect option and with this you replace your chosen items for an empty array, otherwise you'll choose the option where the value is empty val('').
So I looked in the selectpicker.js file, the deselectAll and selectAll functions both filter their respective options by a few arguments (see line 884):
deselectAll: function () {
this.findLis();
this.$lis.not('.divider').not('.disabled').filter('.selected').filter(':visible').find('a').click();
}
A little breakdown:
.not('.divider') //prevents the divider receiving a click event!
.not('.disabled') //ignore any disabled elements
.filter('.selected') / .not('.selected') //depending if its selectAll() or deselectAll()
.filter(':visible') //prevent any non-visible element receiving a click event!?
My problem was the .filter(':visible'), the list was not visible when the click event was triggered so these options were filtered out and therefore did not get 'clicked'/'deselected'.
I amended my version of the plugin and now my 'reset' button works as expected. The new line is:
this.$lis.not('.divider').not('.disabled').filter('.selected').find('a').click();
I have a form with several fields populated by the user and before it is submitted some javascript gets called when a check button. It tries to set the value of the form fields to a variable that exists in the js function.
document.getElementById('var1').innerHTML = test;
alert(test);
I know the javascript is working as expected because I see the alert but the form boxes are not getting populated:
#helper.input(testForm("var1")) { (id,name,value,args) => <input type="text" name="#name" id="#id" #toHtmlArgs(args)> }
innerHTML is used to get/set the body of an html tag, so you're probably ending up with this in the html:
<input ...>test</input>
I think this may work for a <textarea>, but for your <input type="text"> you want to set the value attribute.
document.getElementById('var1').value = test;
If you want to programmatically set an html form field via JS there are many ways to do this and many libraries out there that make it really easy.
Such as various JS two-way component template binding libraries.
For instance, you can simply do the following:
HTML:
<div id="myapp">
<input id="var1"/>
<button>Submit</button>
</div>
JS:
mag.module('myapp',{
view : function(state){
var test= 'tester';
state.button= {
_onclick:function(){
state.var1=test
}
}
}
});
Here is working example of the above example:
http://jsbin.com/ciregogaso/edit?html,js,output
Hope that helps!