How do clear words/images upon form validation? (AngularJS) - image

Just to be clear, in the subject line, it says "words/images". The "words" part is not about clearing the words in the form, but rather the word "required". As for images, these are validation images, like the green checkmark.
I just realized that I had no clue how to clear words/images upon form completion in AngularJS. Basically, the checkmark stays, and the word "required" appears after submitting the validated form. It does so, because now the form is empty. I tried using the $setPristine in the script page,
$scope.imgHolderComments.$setPristine(true);
knowing that it would probably not work. I looked for a workaround, so I checked out this impressive thread (but realized this was more for the validation itself and not added words/images).
Reset form to pristine state (AngularJS 1.0.x)
Then I tried using this code which I had used prior to today for the pre-validation. Or if you will, for the live validation, before submitting the form. I thought I could recycle this, but no.
$scope.checkUrl = 'images/validation/y_square_trans.png';
$scope.loadUrl = 'images/validation/loading.gif';
$scope.crossUrl = 'images/validation/loading_wrong.gif';
$scope.imgHolderComments = '';
$scope.comments = "";
$scope.timeout = null;
$scope.imgHolderComments = ($scope.reviewForm.comments.$invalid) ? $scope.crossUrl : $scope.crossUrl;
That looked so dirty, but thought it could work after pushing the data in. But the image stayed there (as you can see, I tried replacing the checkmark with a cross instead, as I did not want to create a blank pic).
I also googled it, but everything I could find had to do with two things: clearing the form AND removing the coloured frame (red/green). of course, my form already does that. So, I'm still trying to find a way to remove the word "required" and the gif image in my form upon successful validation.
In any case, I created a plunker. You'll have to click on the word "Reviews" to show the form.
http://embed.plnkr.co/QZT1Jzgg9elMMRHwhYel/preview

Have a look at the directives ng-show and ng-hide.
You can set $scope.allGood = true; somewhere in your controller (after validation) and use this directive: <span ng-hide="allGood">Required</span>
Edit:
You might also want to look at the ng-class directive. Example:
<span ng-class="{green: allGood == 1}">Name:</span> and obviously style the class green to your needs.

Related

Link directly to a notebook page in a view

I have an view that extends the current project view, where we add multiple tabs (notebook pages) to show information from other parts of a project.
One of these pages is an overview page that summarizes what is under the other tabs, and I'd like to link the headlines for each section directly to each displayed page. I've currently solved this by using the index of each tab and calling bootstrap's .tab('show') method on the link within the tab:
$(".overview-link").click(function (e) {
e.preventDefault();
var sel = '.nav-tabs a:eq(' + $(this).data('tab-index') + ')';
$(sel).tab('show');
});
This works since I've attached a data-tab-index="<int>" to each header link in my widget code, but it's brittle - if someone adds a tab later, the current indices will be broken. Earlier I relied on the anchor on each tab, but that broke as well (and would probably break if a new notebook page were inserted as well).
Triggering a web client redirect / form link directly works, but I want to show a specific page in the view:
this.do_action({
type: 'ir.actions.act_window',
res_model: 'my.model.name',
res_id: 'my.object.id',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'current'
});
Is there any way to link / redirect the web client directly to a specific notebook page tab through the do_action method or similar on FormWidget?
If I understood well you want to select the tab from the JavaScript (jQuery) FormWidget taking into account that the id could change if anybody install another module that adds another tab
Solution 0
You can add a class to the page in the xml form view. You can use the id of the element selected by this class name in order to call the right anchor and select the right tab item. This should happen when the page is completely loaded:
<page class="nb_page_to_select">
$('a[href=#' + $('.nb_page_to_select').attr('id') + ']').click()
NOTE: As you have said the following paragrah I assume that you know where to run this instruction. The solution I suggest is independent of the index.
This works since I've attached a data-tab-index="<int>" to each
header link in my widget code, but it's brittle - if someone adds a
tab later, the current indices will be broken. Earlier I relied on the
anchor on each tab, but that broke as well (and would probably break
if a new notebook page were inserted as well).
Solution 1
When the page is loaded you can get the tab list DOM object like this:
var tablist = $('ul[role="tablist"]')
And then you can click on the specifict tab, selecing by the text inside the anchor. So you don't depend on the tab index:
tablist.find('a:contains("Other Information")').click()
I think if you have two tabs with the same text does not make any sense, so this should be sufficient.
Solution 2
Even if you want to be more specific you can add a class to the notebook to make sure you are in the correct notebook
<notebook class="nt_to_change">
Now you can use one of this expressions in order to select the tab list
var tablist = $('div.nt_to_change ul.nav-tabs[role="tablist"]')
// or
var tablist = $('div.nt_to_change ul[role="tablist"]')
Solution 3
If the contains selector doesn't convince you because it should be equal you can do this as well to compare and filter
tablist.find('a').filter(function() {
return $.trim($(this).text()) === "Other Information";
}).click();
Where "Other Information" is the string of the notebook page
I didn't tried the solution I'm giving to you, but if it doesn't work at least may be it makes you come up with some idea.
There's a parameter for XML elements named autofocus (for buttons and fields is default_focus and takes 1 or 0 as value). If you add autofocus="autofocus" to a page in XML, this page will be the displayed one when you open the view.
So, you can try to add this through JavaScript, when the user clicks on the respective link -which honestly, I don't know how to achieve that by now-. But you can add a distinctive context parameter to each link in XML, for example context="{'page_to_display': 'page x'}". When you click on the link, I hope these context keys will arrive to your JS method.
If not, you can also modify the fields_view_get method (here I wrote how to do that: Odoo - Hide button for specific user) to check if you get the context you've added to your links and add the autofocus parameter to the respective page.
As you said:
This works since I've attached a data-tab-index="" to each header
link in my widget code, but it's brittle - if someone adds a tab
later, the current indices will be broken.
I assume that your app allow multi-user interaction in realtime, so you have to integrate somewhere in your code, an update part function.
This function will trig if something has changed and cleanout the data to rebuilt the index in order to avoid that the current indices will be broken.

kendoui validation tooltip in custom popup editor not positioning correctly

Please see jsfiddle for example, blank out First Name field to have validation tooltip show. In a normal form the validation tooltip positions correctly to the right of each element. But in the popup editor for the grid it still trying to position the tooltip below the element as if it where editing inline. I have tried <span class="k-invalid-msg" data-for="FirstName"></span>but it doesn't change anything. Is there a setting I am missing to get this working in popupeditor? I guess I could manually modify the .k-tooltip but I am hoping for something more built in that handles the positioning correctly, because I am not very good at css.
As you've discovered, the error template for the grid is different to that provided by the kendo validator when applied to standard inputs.
Unfortunately, the validator that is created internally by the grid does not pass along any errorTemplate that you might define in the options object and by the time the "edit" event fires, the validator has already been created and the error template compiled, hence why setting the errorTemplate in the manner you describe does not work. Really, I think the Kendo grid should respect any user defined errorTemplate option but until it does we have to hack a little bit.
The key is to define a custom template and to apply it in the edit event, but instead of using the options object, set the private instance directly. Not ideal, but it works:
edit: function (e) {
e.sender.editable.validatable._errorTemplate =
kendo.template($('#tooltip-template').html());
}
See this updated fiddle for an example of what I think you might be looking to achieve.
http://jsfiddle.net/nukefusion/eQ2j7/10/
(I would post this as a comment but not enough reputation yet...)
I'm successfully using nukefusion's solution. I, too, fought with the syntax error from jQuery for a long time and discovered through debugging that how you define the template is important. In particular, it appears that the template has to be written on a single line without any formatting, as in:
<script id="tooltip-template" type="text/x-kendo-template"><span class="k-widget k-tooltip k-tooltip-validation"><span class="k-icon k-warning"></span>#=message#</span></script>
If you try to make it "pretty" and format the html in the template, you get the syntax error. I don't know where the real bug is, as this sort of thing shouldn't cause an error. But it does and I stopped worrying about it once I got it to work correctly.

How to force the Drupal form to clear previous results

Recently im working on a project and im trying to generate form elements with the help of ajax technology (implementing a form with codes). the situation is that the user should be able to select from a list of options and then due to his select another list of options should be appeared, then due to his/her select from the second sets of options he/she should see the third series of options. now the problem is that when the user tries to change the first option in the first set, the second option will be regenerate but the third one still sticks on the page. I was trying to use the form_sate['rebuild'] = TRUE
but it did not work and all form elements disappeared. can any one help me to see which code should be implemented and where it should be used?
Without any code it's almost impossible to help, except to say check out the examples modules, specifically the ajax_example module.
The basic principle is that you need a <div> container surrounding your 2nd and 3rd select elements, which will be replaced by the #ajax set on the first element. Then you need another container inside that one surrounding only the 3rd select element, which will be replaced by the #ajax set on the 2nd select element.
Hope that helps.
well.. the form page may contains previous values because of $_POST fields variables..
for example if I want to display clear "add" form on POST submit,
I do this tric to clear drupal previous form values via ajax:
<?php
// AJAX POST handler...
....
$my_form = drupal_render(drupal_get_form("the_form", ...));
$errors = form_get_errors();
if (!$errors) {
// re-render clean form, unset your POST fields....
unset($_POST['link_path']);
unset($_POST['link_title']);
unset($_POST['parent']);
unset($_POST['weight']);
$my_form = drupal_render(drupal_get_form("the_form", ...));
}
?>

MVC3 Submit Ajax Form

I've read lots of different posts on this topic and I will continue to do so and try various things. There's so much variation in the information though that, with my relative inexperience with MVC, etc, I feel like I'm going round in circles a bit.
Here's the situation. I am displaying a (Razor) view in an MVC3 app that contains records in a jqGrid. Double-clicking a record opens that record in a jQuery UI dialog. The original view contains just the that represents the dialog. The invoked action returns a partial view that becomes the content for the dialogue div.
function editItem(gridID, url) {
var rowID = getSelectedRowID(gridID);
if (rowID == null) {
alert('No row selected.\r\nPlease select a row and try again.');
return;
}
else {
var grid = getGrid(gridID);
$("#editDialogue").load(url + "/" + grid.SelectedRowID, function (html) {
$("#editDialogue")[0].value = html;
$("#editTabs").tabs();
$("#editDialogue").dialog("open");
});
}
}
That part works, although I have a feeling it could stand a little bit of cleanup. My real issue is later submitting the form contained in that dialog. It's supposed to post back to an action with the same name, which it does. That action is supposed to validate and save or return the same partial view with validation errors. At the moment I'm trying to just return the view without doing anything else. The view is returned alright but the entire page is replaced, instead of just the contents of the dialog.
I've tried various things, including using Ajax.BeginForm and specifying the id of the dialog div as the UpdateTargetId of the AjaxOptions. Nothing has worked so far. Note that the form being submitted is inside the div so it will be replaced too. Not sure if this is part of the problem.
I'm packing up for the day now so I thought I'd post and see what happens overnight before attacking the problem again in the morning.
jmcilhinney,
You were right to set the AjaxOptions.UpdateTargetId, but you also need to set AjaxOptions.InsertionMode to InsertionMode.Replace.
I had the same issue occurring as well. The fix was to make sure that the jquery.unobtrusive-ajax.is file is on the page. That fixed my issue. Just double check to be sure. I was confident I had all the js files, but found out I was missing that one.

sIFR - override link click with onRelease?

I've got sIFR setup to replace a navigation menu (looks pretty slick). It's individually replacing the LIs and their internal links. I have an onRelease tag that throws properly, extracts the actual href link address, all good so far. I want to tie this into an AJAX page loader, with backwards-compatability (+SEO) for the individual pages being able to load themselves. I've tried return false like I would for standard links, no dice.
I'm assuming it doesn't work because it's onRelease, not onClick or something BEFORE it is already changing the page? onClick doesn't seem to be a valid sIFR function, documentation at http://wiki.novemberborn.net/sifr3/JavaScript+Methods says onRollOver, onRollOut, and onRelease. It would be a shame to have to pitch my entire AJAX system, there is hopefully a good workaround!
There isn't really an option to prevent the default behaviour. You can change it in sIFR.as though. Assuming the <li> contains just a <a> remove the following around line 505:
getURL(sIFR.instance.primaryLink, sIFR.instance.primaryLinkTarget);
That will prevent sIFR from following the URL when you click on the link. It'll still work with right-click though, but you might be able to fix that by changing (line 508):
menu.customItems = menuItems;
to
menu.customItems = [];

Resources