Keeping AngularJS controls states on back button - javascript

I have a button group that acts like a radio button group like the following:
<div class="col-md-10" data-ng-controller="type-controller">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'1'">
Option 1
</label>
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'2'">
Option 2
</label>
</div>
<input data-ng-model="typeId" name="typeId" type="hidden" ng-init="typeId = '1'" />
</div>
When I submit the form, the selected "radio" goes to the input hidden and it works as expected. The problem is if the user uses the back button. Let's say the user is on the page containing the code above, then the page navigates to another one, then if the user clicks the back button, the "state" of the button group is not kept. It resets making the UX not cool.
So how do I keep the value if the user leaves the page and comes back using the back button? I had this same problem in a different project that I could easily fix by triggering the functions that handle the "change" event using jQuery. I would just check the value of the hidden and set the control state accordingly. But now I'm not using jQuery anymore and I don't think I should manipulate the DOM from within my controller.
I'm using Angular and this site is not a SPA, using ajax to get the values is not the case here.

Related

How To Update Hidden Field In Django Form

I am trying to figure out the best approach to modifying a hidden django form field. Or if it's even possible. I had my HTML setup to accomplish this very task and it was working perfectly. However, in order to prevent multiple submissions I had to change my HTML and now I am unable to figure out how to pass a value via an HTML button depending on what the user clicks on.
Previously, I had two buttons defined as outline below:
<button type="submit" class="button1" name="status" value="Saved"><h3 class="txtalgn4">Save</h3></button>
<button type="submit" class="button2" name="status" value="Submitted"><h3 class="txtalgn4">Submit</h3></button>
As stated above, this worked perfectly for the purpose of passing a value to an attribute for my model. The value of status was saved as expected depending on which button the user clicked on.
Now I have updated the buttons to type="button" in response to this issue that I opened up today...How To Prevent Double Submit With Form Validation
I tried using the following code:
<button type="button" class="button1" name="status" value="Saved"><h3 class="txtalgn4">Save</h3></button>
<button type="button" class="button2" name="status" value="Submitted"><h3 class="txtalgn4">Submit</h3></button>
And then I also changed the status field to {{ status.as_hidden }} in my HTML to get the value. This only works if I hardcode the status value in my database structure. I need to be able to get this value dynamically depending on what the user clicks. Is JQuery with Ajax the right approach for this? Is there some simple way to modify the hidden field depending on which button the user clicks?
Is there some better way to go about trying to get this field in a hidden manner? As stated above the HTML way with type="submit" worked perfectly, but caused problems when I was trying to prevent the user from double submitting the form. As in all things programming I solved one problem and created another.
Thanks in advance for any thoughts.
Keep using two submit buttons like you were. But instead of disabling the buttons, you disable the whole form from submitting if once submitted.
First, give your form a unique html ID.
<form id="myform">
...
</form>
<!-- JS code -->
<script type="text/javascript">
$('#myform').on('submit', function(e) {
if ($(this).hasClass('submitted')) {
// prevent submission
e.preventDefault();
return;
}
$(this).addClass('submitted');
});
</script>

Several radio button groups in nested ng-repeat, but only last group shows the value

I have a page where I want to update a form with several radio buttons. I query an api, and use the returned array of objects to populate the current values for the radio buttons. The problem that I have is that only the last set of radio buttons actually shows the value. This is the code that I have (I am using [[ and ]] for the start and end symbols for angular):
<fieldset data-ng-repeat="s in sections">
<div class="form-group">
<div class="col-md-12">
<h2>[[ s.section.name ]]</h2>
</div>
</div>
<!-- Field Item -->
<div class="form-group m-b-20 bg-light" data-ng-repeat="f in s.fields">
<div class="col-md-12 m-b-30">
<h4>[[ f.field.name ]]</h2>
<input type="text" data-ng-model="f.comments" class="form-control input-md underline" placeholder="Comments">
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="pass" class="form-control" data-ng-model="f.field_condition">
<label class="eval-pass"><i class="fa fa-check-circle green"></i> Pass</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="fail" class="form-control" data-ng-model="f.field_condition">
<label class="eval-fail"> <i class="fa fa-exclamation-circle red"></i> Fail</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="n/a" class="form-control" data-ng-model="f.field_condition">
<label class="eval-na"> <i class="fa fa-circle blue"></i> N/A</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="caution" class="form-control" data-ng-model="f.field_condition">
<label class="eval-caution"><i class="fa fa-exclamation-triangle yellow"></i> Caution</label>
</div>
</div>
[[ f.field_condition ]]
<hr>
</fieldset>
So basically, I have several sections, and each section has several fields. Each field has it's own radio button group (I am using the section and field ids to name the radio group). What I currently see is only the last field in each section actually shows the selected radio button. The other fields don't have any selection, even though the value for ng-model definitely does (I am showing the value of f.field_condition just to make sure there is a value).
For each field, I can see that the model is set. And if I select a value manually, I can see that the model changes, so it seems to me that the model is setup correctly. I just don't know why it won't initially show as selected for all rows but the last one.
I should also mention that if I save the form even with the missing radio button selections, the database is updated properly (it doesn't set the values to null, and if I manually change the selected value, it is updated in the db as well).
Does anyone have any ideas? Thanks!
EDIT
Here is a fiddle for this, although, it is working as expected in the fiddle. http://jsfiddle.net/dq8r196v/367/
I tried using the static data that I used in the fiddle, but I am still having the same problem. Does anyone know if this could be a CSS problem? The radio buttons are styled, and I didn't write the HTML or CSS.
UPDATE
I am still having this issue, so I built a new angular app and only used the code that is included in the fiddle that I have created. I am having the same problem with this new app, even though the same code works in the fiddle. I really don't understand what's happening here, but if anyone could shed some light, I would really appreciate it.
I have literally copied and pasted the code from my fiddle into a new angular app, and only the last group of radio buttons in each section is showing the value in the app.
Here is my complete code for the new angular app if someone else wants to try it out and see exactly what is happening: https://pastebin.com/qSR33yfM
I created the app on a single page for simplicity.
Here is the link to a pastebin with the exact json that I am using in my app: https://pastebin.com/utfVVQfT
I fixed the problem you're having by simply adding an array of objects ($scope.values) representing the different radio button options, and using an ng-repeat to create your radio buttons. See the following for the updated code: https://pastebin.com/s3hNzaXX
I know there are semantics around ng-repeat creating new $scopes, and imagine there is a conflict in scopes with your nested ng-repeats where it's binding to the radio buttons incorrectly and at a scope different than you want (the section level ng-repeat).
To confirm this suspicion, you could convert all of your interpolations in the code to use functions and console.log s and f at different points and confirm that field_condition is being set at a level you didn't intend.
Either way, it' best practice to create your radio buttons through data (and using ng-repeat), as is done with the $scope.values array, and a good side effect to doing this is not only can you update the different value options using data through AJAX or however you would like, but you won't have weird angular scoping issues as you're experiencing in your current code above.

Delete AngularUI Accordion on ng-repeat

So I'm trying to add a delete function to my ng-repeating accordion.
The button is displayed and the function is set up, but when the delete button is pressed the page reloads almost and then redirects to localhost:8080/# however it should not redirect to here, and there is nothing suggesting it should redirect to here, not that I can see anyway, maybe this is one of the problems? However I'm unable to see were this would originate from..
As the application isn't hosted yet once the page is refreshed, all of the data is lost, as it is passed to the current editing view, by the view before it, which displays them in a table until you click on one of the rows and get taken to said editing page.
Here is my JS delete function:
$scope.delete = function (index, event) {
if(event) {
event.preventDefault();
event.stopPropagation();
}
$scope.selectedTestScript.Actions.splice(index, 1);
}
And here is my ng-repeat accordion:
<uib-accordion close-others="oneAtATime">
<uib-accordion-group ng-repeat="action in selectedTestScript.Actions" is-open="action.isOpen" ng-click="action.isOpen=!action.isOpen">
<uib-accordion-heading>
<div>{{action.Description}}<button type="button" class="btn btn-xs btn-danger pull-right" ng-click="delete($index, event)"></i>Delete</button></div>
</uib-accordion-heading>
<div>
<label for="actionNotes" class="control-label col-xs-2">Action Notes</label>
<div class="col-xs-10">
<textarea id="actionNotes" type="text" rows="4"ng-model="action.Notes" class="form-control" name="name"></textarea>
</div>
</div>
<div>
<label for="actionExpected" class="control-label col-xs-2">Action Expected</label>
<div class="col-xs-10">
<input id="actionExpected" type="text" ng-model="action.ExpectedOutcome" class="form-control" name="name">
</div>
</div>
</uib-accordion-group>
</uib-accordion>
Any help would be much appreciated, I've tried simplifying the function and removing the if(event) statement and leaving it as a splice, but this also doesn't work.
Thanks in advance.
I guess you have a form surrounding the code you posted?
If that is the case, using <button> with no type specified defaults it to type=submit, which triggers the original HTML form submit, thus the redirect.
You can set type to button to prevent that from happening.
Also action.isOpen==!action.isOpen doesn't look correct, do you mean single =?
Edit: There is actually a paragraph under ui-bootstrap accordion that reads
Known issues
To use clickable elements within the accordion, you have to override
the accordion-group template to use div elements instead of anchor
elements, and add cursor: pointer in your CSS. This is due to browsers
interpreting anchor elements as the target of any click event, which
triggers routing when certain elements such as buttons are nested
inside the anchor element.
http://angular-ui.github.io/bootstrap/#/accordion

What is the best solution: How to combine 2 buttons in one - may be with js?

I try to make my checkout page more friendly and how to do this:
I have guest form`s and save button after them. And after guest info is saved (instead payment option) are show send my order button - this is from one module Cash on delivery, but instead to choice only this i move button to be showed directly.
BUT: Many clients are confused from this "save" button. I want to marge this two buttons in one.
How to do this? What is the best solution: to add some js when for save button or adding new button instead these 2?
You can see the problem page in my live shop here: http://bijutaniki.com/porychka (do not forget to add product like: http://bijutaniki.com/prysteni/8-prysten-na-nastroenieto.html - and shop is on bulgarian)
Now process looks like that:
What i want to do:
I try two times to add new button with js instead these to but without success. May be if use "save" button and add js to click on other "send order" button will be more easy because when "save" been clicked check fields above and if fields are valid show message.
What are you think, how to combine this buttons.
Thanks!
EDIT:
Save button and message:
{$HOOK_CREATE_ACCOUNT_FORM}
<p class="submit">
<input type="submit" class="exclusive button" name="submitGuestAccount" id="submitGuestAccount" value="{l s='Save'}" />
</p>
<p style="display: none;" id="opc_account_saved">
{l s='Account information saved successfully'}
</p>
<p class="required opc-required" style="clear: both;">
</p>
Send order button (with smile):
<div class="cod_cofirm">
<form action="{$link->getModuleLink('cashondelivery', 'validation', [], true)|escape:'html'}" method="post">
<input type="hidden" name="confirm" value="1" />
<p class="cart_navigation" id="cart_navigation">
<input type="submit" value="{l s='Send order' mod='cashondelivery'}" class="extraorderbutton" />
</p>
</form>
</div>
Because prestashop have controllers may be need to show code from some controller?
I guess there is no valid answer without showing us code, I'll try it anyway:
$('NEW_Send_Order_btn').click(function(e){
e.preventDefault();
$('Save_btn').trigger('click');
if($('Save_btn').hasClass('well_done')){
$('Send_my_order').trigger('click');
}
});

Adding extra submit function to dynamically populated jquery .submit

Background
Okay, I have a unique web application, and after reading around on SO and some great other questions, I am still scratching my head as to how I can accomplish this feat. The end result: I must add a cancel button to a form which has populated input fields dynamically after a link click... It is a third stage function which is being activated, and must be able to be run solely within the context of the dynamic form (because there are other modal form windows on the same page)... please follow below for the flow. Any suggestions are much appreciative.
Steps Followed that end input form is affected by
1) User clicks on a link.
2) Modal window opens with dynamically populated fields
3) AJAX/JSON method pulls information through mysql
4) div's and spans populated inside modal window
5) Edit links are added for corresponding fields... Registers event handler to listen to user either clicking "edit", or closing modal window.
6) If user clicks edit, input fields appear, as well as a submit button.
7) on submit,
a) deactivate all other event handlers on other "edit" links
b) send ajax/json
c) activate all other event handlers
d) hide all input fields and 'reset' the modal window for next item edit
html
<form id="updation_station" action=''>
<div class="view_info">
Test 1:<span class="view_test_1"></span>
Edit
<span class="edit_test_1_input"><input type='text' name='test_1_input' /></span>
</div>
<div class="view_info">
test_2:<span class="view_test_2"></span>
Edit
<span class="edit_test_2_input"><input type='text' name='test_2_input' /></span>
</div>
<input type="submit" name="update" id="change_btn" value="Save Changes" />
<input type="submit" name="cancel" id="cancel_btn" value="Cancel" />
</form>
In order to accomplish what I needed, I run $('.edit_link').on('click', doUpdate); to execute the function of the updater... as follows
function doUpdate(e) {
// show input fields, sets variables, etc....
// Turn off the event handler for all the other edit links
$('.edit_link').not(this).off('click', doUpdate);
//Now open the listener for the submit form
$('#updater').submit(function() {
//Now close the editing fields
//closes edit fields, etc...
$.ajax({//do something });
//Now reset the event handlers so the links are re-activated regardless of what was clicked
$.ajax().always(function() {
$('.edit_link').on('click', doUpdate);
});
return false;
});
// hides input fields, etc.... and tells client to go on merry way
};
Unfortunately, I am extremely weary to change the $('#updater').submit(function() { action itself due to complications with some other omitted functionality... I would prefer to only append functions to it and/or touch the html portion, such as..if ($submitted_value == "cancel") { //cancel} else {//act}, but that seems to be an issue because any submit button itself will activate the form itself.
Anyone have any ideas? Snippets That may help?
Hopefully the experts of SO will be a better guide on how I can go about this...
Thank you in advance.
May not be best practice.. but might work
anonymous call
<input type="button" name="cancel" id="cancel_btn" value="Cancel" onclick="$(this).parent().hide()" />
anonymous if two elements deep
<input type="button" name="cancel" id="cancel_btn" value="Cancel" onclick="$(this).parent().parent().hide()" />
hide by div id or class
<input type="button" name="cancel" id="cancel_btn" value="Cancel" onclick="$(".formDiv").hide()" />

Categories