I have a create view where the user and fill some data and if they click on a button a dijit.dialog opens with a list of items to select. Everything works fine, except that when the dialog confirms the selected items it goes to the controller to do some logic and refreshes the create view deleting the data that the user filled previously.
How can I make the dialog persist what the user already filled (maybe going to the controller to set the data before opening it)? Or maybe try to close the dialog, refresh the list that I show on the dialog and part of the create view that uses what the user selected.
Not sure if I make myself clear enough.
Edit
My project is based on Spring Roo:
<form:create .....>
.. inputs and tables ..
<input type="button" ../> //goes to controller and loads page with dialog open
<tiles:insertTemplate template="/WEB-INF/views/dialog.jspx" />
</form>
Dialog code:
<div id="dialog" dojoType="dijit.Dialog">
<form id="items" dojoType="dijit.form.Form">
<jsp:doBody/>
<input id="save" type="submit" name="sendDialogData">
</form>
</div>
I thought that would make the dialog part of the form but just checked with firebug and it is created after the "wrapper" (the div that contains everything)
Related
I'm a newbie to NgbDropdown and related ng-bootstrap code, and I'm having trouble figuring out how to close all previous NgbDropdowns when a new one is opened using the enter key.
I've created a number of NgbDropdowns on a page in my Angular project, and I find that when I click from dropdown button to dropdown button, the previously opened dropdown closes; however, if I TAB from an open dropdown to another dropdown button and use the enter key to open the second dropdown, as may be needed for accessibility, the first dropdown does NOT close. I am left with two drop-downs overlaying each other.
This sequence can be duplicated on the main NgbDropdown example page at https://ng-bootstrap.github.io/#/components/dropdown/examples: on a different button (First example at the top.)
Sequence:
1. Tab to "Toggle Dropdown"
2. Hit the enter key to open the dropdown
3. Tab through the dropdown options, pluse one more time, so that you've
tabbed to the "toggle drop-up" button.
4. Hit the enter key
5. Both dropdowns will be open simultaneously.
Screen Shot
So apparently the code that closes previous dropdowns on click doesn't work when the enter key is pressed on a different button. Not finding much documentation about what can be done with the various Ngb objects in typescript, I am left not knowing how to close all previous dropdowns when a new dropdown is opened with the enter key. All I can think of doing is:
1) Loop over all dropdowns in the ts file, closing them prior to opening the latest. If this is the best solution, I do not see any way to loop over a collection of open drop-downs. Is there such an object/array available to me as part of the NgbSolution, or would I have to add each to an array on my own?
2) Trigger the click event when the enter key is pressed on a button. Again, I am unaware of how to have one event trigger another on an NgbDropdown object.
Any pointers would be appreciated. I've not posted my code here because it is the same as the basic example referenced above.
For your suggestion #1 (loop over all dropdowns and close them), you can implement it as follows:
In your HTML, declare each dropdown as a DOM variable using Template Reference Variables (the # syntax):
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
...
</div>
Add a click handler to the button as follows. This allows you to pass in a reference to the dropdown to the function called by the click handler:
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">Toggle dropdown</button>
The complete HTML for a dropdown should look like this:
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">
Toggle dropdown
</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button ngbDropdownItem>Action - 1</button>
<button ngbDropdownItem>Another Action</button>
<button ngbDropdownItem>Something else is here</button>
</div>
</div>
Add the following as a class variable of your Typescript component. This allows you to reference all the dropdowns displayed in the component from the Typescript file:
#ViewChildren(NgbDropdown) dropdowns: QueryList<NgbDropdown>;
Add a click function to your Typescript component:
closeOthers(clickedDropdown: NgbDropdown) {
// Close all dropdowns
this.dropdowns.toArray().forEach(el => {
el.close();
});
// Open the dropdown that was clicked on
clickedDropdown.open();
}
Now whenever you click on a dropdown (or select it by tabbing and pressing return) it will call the closeOthers function which will:
Close all dropdowns
Open the dropdown that was clicked
Please see this StackBlitz for a working demo.
#Dordrecht - the approach I would take for the functionality mentioned in your comment below would be to create a service as follows:
export class ModalNotificationService {
private _closeModals: Subject<void> = new Subject<void>();
private _closeModals$: Observable<void> = this._closeModals.asObservable();
public emitCloseModalEvent() {
this._closeModals.next();
}
get closeModals$(): Observable<void> {
return this._closeModals$;
}
}
This service would be injected into any component that has modals and those components would subscribe to the observable closeModals$ and then close the modals in their own component. Modify the closeOthers method to call the new service's emitCloseModalEvent method to notify all the other components.
Whats "best practice" for rendering components in a form based on user input?
I want a second input field added to the form when a user clicks option 2 on the dropdown button. I also want this if show cleared when a user clicks another option.
<form>
<button class='test'>my dropdown button with option 1,2,3</button>
<input type=text> input field 1</input>
<!-- if button clicked options 2, add second input field -->
<input type=text>input field 2</input>
</form>
Template.name.events({
'click .test': function() {
// something to render input field 2
}
)};
Thank you.
You can show your elements on conditional basis with helpers.On your second button click you can set a session and use it in a helper.Then in your html page use {{#if}} your element {{/if}}
And for clearing it , destroy this session.
Hope this make sense to you.If any query lmk
I am building an advanced search form, and upon submit of criteria it brings back search results.
I wanted to implement a page loader for this, so on submit it then triggers the loading of the page
This tutorial works for the page itself
https://www.w3schools.com/howto/howto_css_loader.asp
Can anyone help me make this work when the submit button is clicked instead?
You can use JavaScript to show your loader when your submit button is clicked by adding at to the button directly
<input type="submit" onclick="document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';">
or in a separate script-Tag:
<script>
document.getElementById(ID_OF_YOUR_SUBIMT_BUTTON).onclick=function(){
document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';
}
</script>
Your loader would look like this:
<div id="ID_OF_YOUR_LOADER" class="loader" style="display:none"></div>
I am using the example in the jqGrid Demos page located in Row Editing > Inline Navigator, but I need to have my add button out of the navigator like in example Live Data Manipulation > Add Row. I have already placed the add button:
<table id="editgrid" ></table> <div id="pagered" ></div> <input type="BUTTON" id="bedata" value="Edit Selected" />
and the event
$("#bedata").click(function(){ jQuery("#editgrid").jqGrid('editGridRow',"new",{height:280,reloadAfterSubmit:false}); });
My question is, what is the name of the event or the configuration of the jqgrid that I have to use, in order to insert the new row directly in the grid like in the inline navigator example whitout the modal form dialog when I click the betadata button?
I have already set the modal property to false, but it doesn't work,
Any help would be really appreciated
ANSWER:
The name of the event is addRow, I found it in the inline-editing document.
In my ASP.NET app using the crystal report viewer (ver 13.0.2000.0), when the user clicks "Print" and then either prints or cancels out of printing, when they next Drill Down in the report it will hang forever with the crystal dialog "Please wait while the document is being processed" with spinning triangle circle animation.
It does this in IE and Firefox, but it does NOT do this in Chrome: Instead the print button launches the PDF export with the "The viewer must export to PDF to print." messaging. This is what older versions of crystal did.
Right now I'm going down the road of forcing IE and Firefox to do the same thing as chrome - but if there's a real solution to the print problem - I'd rather use that. It seems when a user clicks Print (vs. export) they want to print (vs. export).
I came up with a work around for this. Since Crystal Reports does not allow overriding the buttons I ended up hiding the print button and adding my own print button using JavaScript/jQuery.
Here is some under-the-hood info on how the printing works. When you press the print button it does a postback with the view states and event arguments. The post back returns a PDF file which the browser opens inline. The PDF file is embedded with a print command which is executed when the file is opened.
So what we can do is use a hidden IFRAME to load the printable PDF. This way the main page is not affected. I think the PDF loading inline is what causes the page/browser to corrupt its state.
Place the below code at the top of your ASPX page. You must place it at the top of the page otherwise the print dialog will be off the screen if you put it at the bottom.
Here is the HTML:
<iframe id="HiddenFrame" name="HiddenFrame" style="display: none;"></iframe>
<form id="PrintForm" action="MyPage.aspx" method="post" target="HiddenFrame">
<!-- Change the name if your object is not named 'CrystalReportViewer1' -->
<input type="hidden" name="__CRYSTALSTATECrystalReportViewer1" id="CRState" />
<input type="hidden" name="__VIEWSTATE" id="VState" />
<!-- Change this value to match your CrystalReportViewer object's name. -->
<input type="hidden" name="__EVENTTARGET" value="CrystalReportViewer1" />
<!-- This is the print command that is sent. -->
<input type="hidden" name="__EVENTARGUMENT" value='{"text":"PDF", "range":"false", "tb":"crpdfprint"}' />
</form>
As mentioned above, the IFRAME will load our PDF. The form is used to do a POST to the server with the view states and event arguments. The target attribute tells the form to load in the IFRAME.
Here is the JavaScript:
// Hide the print button.
$('#CrystalReportViewer1_toptoolbar_print').hide();
// Inject our own print button. You can apply the same icon to your print button using CSS to make it look like the original icon.
$('#CrystalReportViewer1_toptoolbar_print').parent().append('<div id="PrintButtonOverride"></div>');
// When user clicks our print button, copy the states and submit the form.
$('#PrintButtonOverride').click(function () {
$('#CRState').val($('#__CRYSTALSTATECrystalReportViewer1').val());
$('#VState').val($('#__VIEWSTATE').val());
$('#PrintForm').submit();
});
The click event copies the two view states from the main page and then submits the form. I wrote this post quickly so I apologize if I left something unclear.