I have a <h:selectOneMenu>. Depending on what is selected will be shown one of the many <div>s related to the selection and will be hidden the others.
Each <div> has some <h:inputText> that write to different #ViewScoped beans. Some of this <div>s even write to the same properties in the beans.
Ex.
<div>
<h:outputLabel for="list" value="Items"/>
<div>
<h:message for="list"/>
<h:selectOneMenu id="list" value="#{bean.selectedItem}" >
<f:selectItem itemLabel="Select one"></f:selectItem>
<f:selectItems value="bean.someItemsList" />
</h:selectOneMenu>
</div>
</div>
<div id="item1">
<!-- some other input fields -->
<div>
<h:message for="item1input1"/>
<h:inputText id="item3input1" value="bean.thisIsTheSameProperty" />
</div>
</div>
<div id="item2">
<!-- some other input fields -->
</div>
<div id="item3">
<!-- some other input fields -->
<div>
<h:message for="item3input1"/>
<h:inputText id="item3input1" value="bean.thisIsTheSameProperty" />
</div>
</div>
The problem: When I select an item that will display a <div> (ex. <div id="item1">) and there is also another hidden <div> (ex. <div id="item3">) that writes to the same bean properties (ex. value="bean.thisIsTheSameProperty") and this properties are annotated with javax.validation.constraints.#NotNull, even I give a value to this input fields, when I submit the form, I think JSF runs also the hidden <div> (which normally has no input set).
What I see during debugging: When the form will be submited I see the setter of the bean will be called twice. The first time the bean properties will be set with the correct valeus I typed in but the second time the setter will be called with null values. So the validation will fail because of the #NotNull.
My assumption is that JSF tries to set the bean values twice, one for the input fields on the shown <div> and the second time for the hidden <div> (because they point to the same bean properties), but for the hidden bean there are not input fields set (they are null).
I show/hide the <div>s with jQuery depending on the item selected from the <h:selectOneMenu>.
Ex.
$('#item1').show();
$('#item1').hide();
$('#item2').show();
$('#item2').hide();
$('#item3').show();
$('#item3').hide();
Is there a way to say JSF to not consider the hidden <div>s at all?
You seem to be assuming that hidden inputs (hidden via CSS) are not submitted to the server. This assumption is wrong and it is a plain html thing btw, not JSF related at all.
See e.g. Stop an input field in a form from being submitted
But still, it would allow client-side manipulation via a browser developer tool to 'attack' you application. JSF, contrary to all the hyped javascript UI frameworks is a full grown 'MVC framework' that has build in protection against client-side manipulation/tampering and CSRF, XSS for which you'd need OWASP related functionality in other framework. (That and other things makes JSF (with PrimeFaces, OmniFaces and DeltaSpike) for me still a great framework to quickly develop business oriented applications.)
You'd better use ajax to conditionally render one div or the other but you cannot 'update' the divs when they are defined like you have them.
See also:
Ajax update/render does not work on a component which has rendered attribute
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
The answer from #Kukeltje and comment from #drkunibar worked for me.
I modified it a little.
Actual solution:
$('#myForm').submit(function() {
if($('#list').find(':selected').val() === 'itemOption1') {
$('item3').remove();
} else if($('#list').find(':selected').val() === 'itemOption3') {
$('item1').remove();
}
});
I check to see which option is selected. If option1 is selected then I remove the div with iditem3 from the DOM, or else if the option3 is selected then I remove the div with iditem1 from the DOM.
In this way the binding bean.thisIsTheSameProperty is transmitted only one and the values will not be overriden.
Thank you.
Related
In my Office add-in I have a checkbox like the following:
<div class="ms-CheckBox">
<input id="inputId" type="checkbox" class="ms-CheckBox-input" />
<label id="labelId" role="checkbox" class="ms-CheckBox-field" aria-checked="false" name="checkboxA" for="inputId>
<span class="ms-Label">Text</span>
</label>
</div>
I want to retrieve through JavaScript its checked status (or its aria-ckecked status, I'm still not getting the differences between them), which I thought was through document.getElementById( 'labelId' ).checked, since it's specified in the documentation that they have an optional checked member, but I only get an undefined with it.
I'm very new to these technologies and have a couple concerns:
Does "optional member" mean that I have to explicitly create it so that it exists? If so, how can I do that?
However the checked member may come to existance, do I have to manually handle its value every time it's clicked on by the user or is it already internally managed and I simply haven't found the way to access it yet?
Maybe I just can't see a mistake I've made on the html code for the checkbox?
Thank you in advance!
You have several sources of documentation on Office UI Fabric depend on framework you are using or about to use. Your choices are:
JavaScript only (no framework)
React
Angular
Form the look up table you would choose JavaScript only link and follow it to find the component you are interested in. Before that I would suggest to read "Get Started using Fabric JS".
Now when you have documentation on checkbox component of vanilla JS implementation, follow the steps to set up your checkbox. This would include:
Confirm that you have references to Fabric's CSS and JavaScript on your page
Copy the HTML from one of the samples below into your page.
<div class="ms-CheckBox">
<input tabindex="-1" type="checkbox" class="ms-CheckBox-input">
<label role="checkbox" class="ms-CheckBox-field" tabindex="0" aria-checked="false" name="checkboxa">
<span class="ms-Label">Checkbox</span>
</label>
</div>
Add the following tag to your page, below the references to Fabric's JS, to instantiate all CheckBox components on the page.
<script type="text/javascript">
var CheckBoxElements = document.querySelectorAll(".ms-CheckBox");
for (var i = 0; i < CheckBoxElements.length; i++) {
new fabric['CheckBox'](CheckBoxElements[i]);
}
</script>
To get the status of your checkbox use method getValue() which returns true or false whether the component is checked or not.
I have two sets of data: "heat" and "cold", which are retrieved from another provider. This data is quite unorganized and I have removed lots of stuff in the code just to show the essential part of my problem. "Heat" and "cold" both contain properties that the user has to fill in. This property however is dynamic and the amount of properties is not fixed (hence it is in a loop as shown in the code).
My goal is to hide/disable the submit button, which is located all the way down, whenever one single input field in the list in either sets of data is empty. This should also preferably work on Internet Explorer 9, where the 'required' tag is not supported.
I have tried:
Adding the required tag. This unfortunately does not work in IE9 and I have some issues even in Google Chrome because it is still submitting my form. (I added the form tags too)
Adding Ng-show on the submit form. I checked whether the userInput is empty, but this still does not work.
Now you may ask, why wouldn't I just check in my controller whether these properties are empty in my submit method? While it is a good point, I can not access this dynamic data very easily in my controller. Hence, I need a solution that will hopefully fix this problem with no/mimimal effort in the controller.
Code:
<!--Start wrapper!-->
<div class="wrapper">
<div ng-repeat="(code, program) in data.old.heat">
<div class="row" ng-repeat="(componentId, component) in program">
<div class="inputForm">
<!--This field may not be left empty!-->
<input type="text" class="form" ng-model="component.userInput">
</div>
</div>
</div>
<div ng-repeat="(code, program) in data.old.cold">
<div class="row" ng-repeat="(componentId, component) in program">
<div class="inputForm">
<!--This field may not be left empty!-->
<input type="text" class="form" ng-model="component.userInput">
</div>
</div>
</div>
</div>
<!--End of wrapper !-->
<div class="submitPanel">
<button ng-click="submit()">Submit</button>
</div>
Here ya go : https://jsfiddle.net/DIRTY_SMITH/zxbe5rt0/
function validate(){
var text1 = document.getElementById('text').value;
if (text1.length > 0){
alert("went through");
return true;
}
alert("did not go through");
return false;
}
Not specific to angular, but you could check if it has characters via jQuery.
Html
<div class="submitPanel">
<button class="submit-btn" ng-click="submit()">Submit</button>
</div>
jQuery
$('#form input').blur(function()
{
if( $(this).val().length === 0 ) {
$(this).parents('.submit-btn').addClass('hide');
}
});
CSS
.hide{
display:none;
}
I have two options for you, but they both include ng-disabled (https://docs.angularjs.org/api/ng/directive/ngDisabled).
You can put this attribute on the button and you can either call a function on the scope in that attribute and check if all values are given.
So like: ng-disabled="checkInputs()".
Or
You wrap a form around all your inputs, give the form a name like name=form and set the required attribute on all inputs. (EDIT: you could use ng-required="true" for IE9.)
Then you could say ng-disabled="!form.$valid".
I am using jQuery and bootstrap to give drop-down search suggestions.Following is the html code.But when I type something in the search form and then clear the form.Two forms apears as in the picture.Why? I am new to jQuery. Thanks for any help.
<div class="container">
<div class="row">
<div class="span6 offset3">
<form class="form-search">
<input type="text" id="month" name="month" class="input-medium search-query">
<button type="submit" class="btn">Search</button>
<div id="suggestions">
</div>
</form>
</div>
</div>
</div>
<script>
jQuery("#month").keyup(function(){
ajax('search', ['month'], 'suggestions')});
</script>
EDIT:
I am using web2py framwork.This is the search function's code:
def search():
if not request.vars.month: return dict()
month_start = request.vars.month
selected=complete('piracyfinder',month_start) #this line get the search results
return DIV(*[DIV(k['title'],
_onclick="jQuery('#month').val('%s')" % k['title'],
_onmouseover="this.style.backgroundColor='lightblue'",
_onmouseout="this.style.backgroundColor='white'"
) for k in selected])
It appears you are using the same function (i.e., search()) to fill in the suggestions as well as to create the form (though that function doesn't process the form when submitted). According to the logic, when request.vars.month is either empty or does not exist, the function returns an empty dict. This will result in the associated view (i.e., /views/[controller name]/search.html) being executed and returned. Presumably the search.html view contains the HTML code shown above. So, when you clear the input box, the keyup handler is triggered and sends an empty month variable, which results in a new copy of the form being sent back and inserted in the "suggestions" div. You can avoid this problem by checking whether request.vars.month exists:
if not request.vars.month:
return '' if 'month' in request.vars else dict()
A better approach might simply be to use different functions for the search form and the suggestions given that they do completely different things and don't share any code.
if not request.vars.month also applies to the month var existing but being empty. Therefore, it's returning the form.
You need to do one of these:
Have your "suggestions" code be in a different page/file
Add a isAJAX variable to the request (or some other way to identify AJAX requests)
Check if the variable exists, rather than checking if it is falsy.
Is there a specific reason that most everyone implements edit-in-place as a shown 'display' div and a hidden 'edit' div that are toggled on and off when somebody clicks on the associated 'edit' button like so?
<div id="title">
<div class="display">
<h1>
My Title
</h1>
</div>
<div class="edit">
<input type="text" value="My Title" />
<span class="save_edit_button"></span>
Cancel
</div>
</div>
Everywhere I look, I see edit-in-place basically handled like this. This approach certainly makes sense when you are rendering all views on the server side and delivering them to the client. However, with pure AJAX apps and frameworks like backbone.js, it seems that we could make our code much more DRY by rendering edit-in-place form elements on the fly as necessary, possibly even making a factory method that determines which form element to render. e.g.
an H1 element with class "title" is replaced by <input type="text" />
a span with class "year_founded" is replaced by <input type="number" min="1900" max="2050" />
a span with class "price" is replaced by an input with the appropriate mask to only allow prices to be input.
Is this practice of rendering all edit-in-place form elements a historical legacy leftover from when pages were rendered on the server-side?
Given the flexibility and power we have with client-side MVC frameworks like Backbone.js, is there a reason for not creating and inserting the form elements on the fly when necessary using a factory method? Something like this:
HTML
<div id="description">
Lorem ipsum dolar set amit...
</div>
<span class="edit_button"></span>
Backbone.js View
events: {
"click .edit_button": "renderEditInPlaceForm",
},
renderEditInPlaceForm: function:(e) {
var el = $(e.currentTarget).previous();
var id = el.attr('id');
var value = el.text();
var tagName = el.tagName();
var view = new editInPlaceForm({
id: id,
type: tagName,
value: value
});
$("#id").html(view.render().el)
},
Where editInPlaceForm is a factory that returns the appropriate edit-in-place form element type based on tagName. This factory view also controls all its own logic for saving an edit, canceling an edit, making requests to the server and rerendering the appropriate original element that was replaced with the .html() function?
It seems to me that if we use this approach then we could also render the <span class="edit_button"></span> buttons on the fly based on a user's editing rights like so:
<h1 id="title">
<%= document.get("title") %>
</h1>
<% if (user.allowedToEdit( document, title )) { %>
<span class="edit_glyph"></span>
<% } %>
where the allowedToEdit function on the user model accepts a model and attribute as its arguments.
It's an interesting idea. The devil is in the detail.
While your simple example is easily rendered as an editable form on the fly, things quickly get trickier when dealing with other data types.
For example - suppose my edit form requires the user to choose a value from a select list. On the display form I can simply display the user's choice, but for the edit form I am going to need those other available choices. Where do I hide them on the display? Similar issues exist for checkboxes, radio lists...
So, perhaps we should consider rendering the edit form, and then deriving our display-view from that?
After 5 Backbone apps I came to same thoughts.
When things are complicated you have forms to show relations between user data,
but in simple cases you just need input, select, checkbox over h1, div or span
Now I am searching for jQuery plugin to make simple in place editing without ajax.
jQuery but not Backbone becuase I don't want to be tight coupled with Backbone for such small thing.
Likely to wright my own jQuery + Synapse plugin http://bruth.github.com/synapse/docs/.
Synapse for binding with model and jQuery for input placing
I have a jQuery selector that is running way too slow on my unfortunately large page:
$("#section").find(":visible:input").filter(":first").focus();
Is there a quicker way to select the first visible input without having to find ALL the visible inputs and then filtering THAT selection for the first? I want something like :visible:input:first but that doesn't seem to work.
[Edit]
Here's the basic idea of what #section looks like:
<div id="section">
<div>
Some text <input type="text">
</div>
<div>
etc. etc. <input type="text">
</div>
</div>
$(":input:visible:first", "#section").focus();
If you first filter for the type of control you avoid checking the :visible on all the #section's elements.
It seems like you need only to catch the first input type="text" visible.
This should be a bit faster.
$("input[type='text']:visible:first", "#section").focus();
How about adding class="default_field" to the default field for each page, then using $('.default_field').focus();?
How easy this is to do depends on your server-side technology of course, but the advantages are that it takes the processing burden off of the client (which is extra important for IE6), and it also gives you the flexibility to choose a default input other than the very first one on pages where it's appropriate.