How to reRender a rich:dataTable which is inside a4j:repeat? - ajax

I have sth like this:
<a4j:repeat value="#{results}" var="hdr" rowKeyVar="idx">
<rich:dataTable var="item" value="#{results}" id="tbl#{idx}" first="#{idx}" rows="1">
<a4j:commandButton value="update this table only" reRender="tbl#{idx}" />
</rich:dataTable>
</a4j:repeat>
When I check from the output html, the data table has id like form:0:tbl that has no idx at the end.
The reRender will work when there is only one row in the results.
So here comes some questions:
Why doesn't dataTable's id works with EL expression while the "first" attribute works nicely?
How does reRender work that even I just specify tbl it can still be resolved while the actual HTML id is something longer like form:0:tbl? (if I know how does reRender work, I maybe able to hack it to work with a4j:repeat...)
Is there any technique or workaround that I could use to refresh only a specific dataTable that is inside a4j:repeat?
In fact I have successfully reRendered the whole a4j:repeat block surrounded by s:div. But refreshing the whole block would reset the scrollbar so it isn't desired....

For 1, it is possible that the life cycle of the table is in a different phase.
For 2, it refers to UIComponent.findComponent in fact for looking up a component given an ID.
For 3, perhaps try to use UIComponent.findComponent() or #{rich:clientId('id')} to see whether the actual HTML element ID of the a4j:repeat embedded rich:dataTable to be retrieved.
If yes, then somehow reRender can be made to work. If no, look if there is anything that can override how reRender looks for component.

Okay latest experiment shows that simply using the rich:dataTable id can do.
Keys to remember:
Inside a4j:repeat, the absolute name of the id of dataTable will have something like :0: :1: for the corresponding index.
However, to locate it, simply using the same id as defined in rich:dataTable is okay. Don't append any suffix at the end.
When observing the ajax data from Chrome, the reRendered portion is just the same related dataTable of the component.
Conclusion, think too much, failed to try the simplest solution at the start.

Related

Disable other inputtext on change of one inputtext

I'm using JSF2.1 with PrimeFaces 4.0 and surprisingly I'm unable to find a simple solution, how to disable a field if another field is already filled instead. E.g. if I enter a number in the "plus quantity" field and I leave the field by clicking or using tab, the "minus quantity" field should be disabled.
All I found is to do something like this
<p:inputText id="minusQty" disabled="#{not empty order.plusQty}"/>
<p:inputText id="plusQty" value="#{order.plusQty}">
<f:ajax update="minusQty" />
</p:inputText>
but I find it a bit heavy to call the server for such a simple task. I also don't want to add custom JS code. I guess there's a built-in way in JSF/PF but I cannot find it...
but I find it a bit heavy to call the server for such a simple task
Measure it instead of making assumptions.
I also don't want to add custom JS code
It boils down to just using the right tool for the job. The code which you've so far looks okay, apart from the <p:ajax> and <f:ajax> mixup (the <f:ajax> doesn't support update attribute). I'd only use <p:ajax partialSubmit="true"> to reduce request payload, especially if this is part of a relatively large form.
Might you eventually go in the JS direction, keep in mind that enabling/disabling a HTML DOM element in client side doesn't enable/disable the JSF component in server side. In other words, when you do so with pure JS, then hackers will still be able to submit the value anyway. Always keep this in mind when considering either client or server side for some tasks.

Knockout set initial value of an input field where html is allowed

I have two input fields first name and last name.
Application was running really well.
Suddenly someone came in from Mars and input something like this in those input fields
*(~'##~>?<+!""*%$)!
for both first name and last name. Now don't ask me why he did this cause in Mars this is very common. You can try it on this fiddle
http://jsfiddle.net/farrukhsubhani/3RjRF/
This text then went into my database and now when i retrieve it it came back like this
*(~'##~>?<+!""*%$)
which is ok for me as its html and I can place it back into knockout and it gets populated as html as you can see in fiddle above. However this Mars guy then thought that on Earth this is not a nice name to be with so he tried to edit field.
The above fiddle is kind of that edit page which shows him old value at bottom and two fields at top. He does not know html so he thought we have changed his name in input fields however I need to know
When passing text to knockout to give initial value to an input field is it possible to tell it that consider this text as html so it renders properly in input field
The other way around is to send him to http://www.w3schools.com/tags/ref_entities.asp and tell him about reserved HTML characters. This info has been stored in database (using Entity Framework simple person.fname and person.lname both with attribute AllowHTML) so on my fiddle i have just placed it in two variables and you can see how actual text boxes are different than html below. If i dont bind using Knockout then actual text is shown in these boxes and user can edit <>' signs without any problem.
Anyone with a solution before he leaves our planet. This can change alien life on our planet.
Update
If i go into this field and paste (~'##~>?<+!""*%$)" binding works fine and you can copy this and paste it into fiddle to see that. However its not taking that value from Javascript variable to knockout expects it to be a string and html special characters are not shown properly in input field.
We have done another test without Knockout and this text does get rendered within the field when you try to edit it its fine.
We have updated JSfiddle to work without JQuery and its the same result if you store it in a js variable and give not value to input field
http://jsfiddle.net/farrukhsubhani/3RjRF/3/
If we assign value to input field and just use jQuery to populate fullname then it works
http://jsfiddle.net/farrukhsubhani/3RjRF/4/
This last fiddle is a working example and we want Knockout to do what JQuery is doing.
I think the question then comes to how can this text be stored in javascript variable and placed into input field as html text so special characters appear unescaped. You can try unescape on jsfiddle that did not work for us.
Somewhere along the trip into (or maybe out of) your database, the value is being HTML-escaped. It's not Knockout itself that's doing it. You're going to need to track that location down, but you can't just disable it; you're going to have to replace it with something that sanitizes the result or otherwise you're opening yourself up to cross-site scripting attacks (any <script>s from external sources inserted into the input would have complete access to your data).
Any time you see the html: binding used, warning bells should go off in your head and you should VERY carefully to check to ensure that there's NO possibility of raw, unexamined user input making it into the string that gets displayed.
Ok here is what i did at the end
http://jsfiddle.net/farrukhsubhani/3RjRF/7/
I have done following:
I have added value attribute to input field and placed the input text as it came from server into it. Because I am using TextBoxFor in MVC it did that for me.
Before I apply knockout binding I have picked this value up using $('#kfname') and passed it to the actual binding so it used the value that came from server. Previously it was passed like (#Model.fname,#Model.lname)
I think what this did was allowed jQuery to pick up the value and assign it to binding instead of variable
ko.applyBindings(new ViewModel($("#kfname").val(), $("#klname").val()));
Hopefully this would help someone using knockout.

CakePHP 2.2: Pre-populate AJAX "update" div?

This question is a little n00b-ish, but I haven't been able to find a satisfactory solution in the CakePHP docs or via google.
I'm trying to make a simple AJAX form that will update some information in a database, and also display that information on the page. The whole process seems straightforward enough, except I can't figure out how to pre-populate the update div.
In my view code, I have
<div id="interestingContent"></div>
<?
echo $this->Form->create();
// create form fields here
echo $this->Js->submit('Save', array('update'=>'#interestingContent');
echo $this->Form-end();
echo $this->Js->writeBuffer();
?>
This works great, and when the form is submitted, my controller correctly calls
$this->render('ajaxview','ajax')
and updates the #interestingContent div appropriately.
So, the question: What's the best way to pre-populate #interestingContent from the database? Of course I could just repeat the code from ajaxview.ctp inside #interestingContent, but it seems there must be a DRY way to do it.
My first thought was to make ajaxview.ctp an element, since I'm basically trying to embed one view inside another. That seems hackish to me, though, since my controller would then be rendering an element's view directly. I also considered the new view blocks in 2.1/2.2 but that doesn't seem right either.
I'm certain this sort of thing comes up all the time. Is there a generally accepted method of doing this?
I had the same problem. It may be hackish, but using an element wil do the job.
First, create an element for representing your bd content.
In your form view, you use the element.
And you create another view that will contain only the element. This view will be the response to your ajax request. By using an element, you prevent code duplication.

Struts 2 - Conditionallly display elements on page based on validation errors

I'm looking into the fielderror tag for struts and was wondering if it was possible to conditionally show certain elements on the page based on whether or not there are any validation errors. I want to do something like this (which currently does not do what i want it to):
<s:fielderror>
This is a test link
<s:param>field1</s:param>
<s:param>field2</s:param>
<s:param>field2</s:param>
</s:fielderror>
I would like the anchor tag to show up ONLY if one of the fields referenced by the param tags is invalid. In other words, if something is invalid in this fielderror block, I would like to display some HTML. The way it is coded above, the anchor tag is always displayed.
I think I can certainly do this with jQuery, but i was wondering if there was a way to do this natively in Struts that perhaps I'm overlooking. I've tried looking at things like the label and title attribute, but nothing seems to be working.
thanks in advance!
~j
There's nothing out-of-the-box, at least not like the way you want it.
Personally, I find your construct quite counter-intuitive: it doesn't execute/render like it reads.
A few options: do it "manually", create a tag to do it, or do it outside of the view. All rely on using ValidationAware.getFieldErrors() to grab the map and do some minimal logic.
The manual approach would use <s:if> to check for the presence of fieldErrors['fieldName'] for each field. Wrapped up in a simplistic JSP-based custom tag would produce something like:
<if:fieldErrors for='field1, field2, field3'>
<a ...>
</if:fieldErrors>
IMO doing most of the work in Java is cleaner, and easier to test. This could mean doing all the work in the action (or utility) and exposing only a single flag to the view, or using a thin JSP-based tag to call the utility. Either way, it's easier to test outside of a container, and removes inappropriate view logic.

Reload the page without submitting it back to the server

the problem I have is that I have two sets of values in a drop down list. If type 'A' is selected I want a text box to be populated with a value from the database and be read only. If Type 'B' is selected the box is to be empty and editable.
My original code is written in jsp/struts and I have sort of achieved this by using
onchange="javascript:submit()" to reload the page, but this has the obvious drawback of saving any changes you have made which means you can't really cancel.
I also have other problems with the serverside validation due to this method.
Is there a way of making a jsp page reload on change, that way I could write javascript to change the way the page looks according to the values held in the session. That way the save/submit function will only be called when the page has properly been filled out and the server side validation will work as designed.
I know that this is something that AJAX is good at doing but I am trying to avoid it if possible.
AJAX is your only other option my friend, unless on the original page load you load all the other possible values of the Text Box so you don't need to go back to the database. Well, you could try putting the text box in an IFRAME, but you will probably run into more problems with that approach than just going with AJAX.
Without AJAX what you are asking is going to be difficult. Another option (which is ugly) is to write out all possible values for the second list box into a data structure like an array or dictionary.
Then write some javascript to get the values from the data structure when the user selects from the first list box. The amount of javascript you will have to write to get this done and to do it correctly in a cross browser way will be much more difficult than simply using AJAX.
Not sure why you'd try to avoid AJAX in today's world, the JS libraries out there today make it so simple it's crazy not to try it out.
I just had to replace a page that was written as Vincent pointed out. I assume at the time it made sense for the app, given the relative size of the data 4 years ago. Now that the app has scaled though, the page was taking upwards of 30 seconds to parse the data structures repeatedly (poorly written JS? maybe).
I replaced all the logic with a very simple AJAX call to a servlet that simply returns a JSON response of values for the 2nd drop down based on what was passed to it and the response is basically instant.
Good luck to ya.
One way is to change the form's action so that you submit the form to a different url than the "save" url. This lets you reload certain aspects of the form and return to the form itself, instead of committing the data.
<script>
function reload() {
document.forms[0].action="reloadFormData.jsp";
document.forms[0].submit();
}
</script>
<form action="saveData.jsp" method="post">
<select id="A" name="B" onchange="reload()"><!-- blah --></select>
<select id="B" name="B"><!-- blah B --></select>
<input type="submit">
</form>
If I understand you correctly, that you want either a dropdown (<select>) or a textfield (<input type="text">) depending on a choice (typically a checkbox or radiobuttons) somewhere above in a form?
I that case you may need to handle the two types of input differently on the server anyway, so why not have both the selectbox and textfield in the area of the form with different names and id and one of them hidden (display = none). Then toggle visibility when the choice changes. On the server you pick eiter the selectbox or textarea input (wich will both be present unless you disable (disabled="disabled") them too, wich I think is uneccesary) depending on the choice input.
Of course if you expect that the user usually just need the text-input, and a few times only, needing a massive list; it would be better to use ajax to retrieve the list. But if it's the other way around (you need the text-field only occationally), as I assumed above, it will be faster to have both present in the initial form.
If the drop down only contain easily generateable data, like years from now to houndreds of years back it could even be much faster (requiring less bandwidth on the server) to generate the data client side using a for loop in Javascript.
I know a taglib that can fit to your problem:
AjaxTags.
I use this taglib in my J2EE projects and it is very simple to integrate it into web applications.
This taglib give you several tags designed to execute AJAX request in your jsp files.
Here is the description of each tags: http://ajaxtags.sourceforge.net/usage.html
The tag which will help you is the ajax:select tag. It allows you to populate a select tag which depends on an other field without reloading the entire jsp page.
If you more informations about it, ask me and i'll try to answer quicky.
Along the lines of what Strindhaug said, but if you need dynamic data:
Could you have the backend write JS into the page, and then the JS would change the form as required? The backend could propagate some variables for descriptions and such, and then the JS could change/update the form accordingly. If you aren't familiar with this, libs like jQuery make things like this easier and more cross-browser than rolling-your-own (at least in my experience).
Aside:
If you're not using AJAX because it was hard to code (as I didn't for a while because my first experience was from scratch and wasn't pretty), as others have said, libs like MooTools and such make it really easy now. Also, there is not shame in using AJAX properly. It has a bad rap because people do stupid things with it, but if you can't simply write premade values into the form or you have to do live look ups, this is one of AJAX's proper uses.

Resources