CheckboxList not retaining it's check mark on postback - javascript

Checkboxlist control in a repeater control & ASP.net C#. Whenever I check its items it gets uncheck automatically. I am also calling this method when the page is not postback as well but it is not working & gets uncheck although I get the values but clears out the checkmark. I do not want to use the session.

If you are in page load re-binding the repeater then you lose the settings. So you need to only bind on first load
(if IsPostBack = false then databind)
So if you re-bind the check boxes each time, then you lose their settings. The other way is to create a array or better yet a dictionary pair list - when you check a item, ALSO save that setting in the dictionay list based on row index. Then you can re-bind on load or as you like, and in the row data bind event, you set the value of the check box based on the dict pair list you maintain (you have to save that list in viewstate or session).
So, it is MUCH less work to simply ensure that you ONLY fill + bind on first page load. If you at any time re-bind the repeater, then you lose your settings. So they will persist ad survive round trips (post-backs), but ONLY if you bind one time on first page load.
It not all that hard to build up a "list" of you made choices and then on row data bind event check + set the values from that small list of choices. But as noted, it obviously easier to just avoid re-binding. However, in the cases that you can't avoid a re-bind, then you need to write your own code to persist the choices.

Related

How to set cascade select2 value onClick

I have three select2 lists next to each other, first independent, second dependent on first, third dependent on second (cascading lists), that works as expected when I normally populate them by selecting some options. I have created a dynamic action that fills these items with values that I calculate when I click a button, but after the click, only the first select2 have selected value. The second and third value remains empty. When I check the session, all items have value in them. It appears that when I click the button that for a millisecond list are filled but after that values disappear. So my question is, how do I transfer values from server-side to client-side. I tried to refresh items, I have played with jQuery without success, also I have tried to separate dynamic action to set values separately but nothing worked. Values populate correctly so that is not the problem. Please help
Thank you in advance for your answer.
Is lazy loading checked for the select2 that are subject to this behaviour (Item -> Setting -> Lazy loading)? If so try unchecking it

Refreshing field value underlying record after quick creating record

I have an entity form (Entity A) which contains an subgrid to display linked records of another entity (Entity B), where multiple B records link to one A record.
Records of entity B are linked to entity A by clicking the '+' icon on the subgrid, filling out an quick create form for entity B and saving. After the save, the newly created record B shows up in the subgrid on the form of record A: all as expected.
When filling in the quick create form for entity B, a field containing an amount needs to be filled. After saving, a server side plugin fetches all records of entity B linked to the specific record of entity A, calculates the sum of all their amounts and fills the total amount in a field on the form of the record of entity A. This also works as expected, the newly calculated value is stored in the database. The problem is that the field that displays the total amount on form A does not refresh. It keeps on displaying the same amount it did when the form was loaded and only updates after a full page refresh. The value though, is updated every time a new record of entity B gets linked. The value on A only shows it's 'new' value when the page is refreshed.
The problem is that the users link 10+ records of B in a row, without refreshing. We get the request to make the field refresh automatically quite a lot, but i have no idea if this can be done, so: Is it possible to refresh (/re-render) a field on the form of entity A on the on save event of entity B? I presume this has to be done in javascript, since it is the client side representation of the fields value and the field value is already correctly stored in the database.
Thanks!
Using JavaScript, there is a grid refresh event you can subscribe to. From there you have a couple options.
In the refresh event you could trigger a rest call to retrieve the value from the server, and then update the value on the form. I'd also disable submit for the field as well, since you don't want the client updating it.
Or- Call save explicitly. You'd either have to ensure the form is valid or change all required fields to no longer be required to allow the save to happen. The save event will return the updated value from the database and automatically update the form.
If you've never made a rest call before, the first option is probably harder, but IMHO, it is the better option.
If helps. it can be done in C#. You can make plugin using the logic you described here.
That plugin would be registered using Plugin Registration Tool. you would have to add two steps for Entity B. First one would have Create message, and the second one Update. For the second step you would select just the amount filed update, so it is triggered only when that filed is updated.
It can also be done using Rollup Fields. They can be updated on click, but also have automatic update on every 12 hours, if that is frequent enough for you.
I don't have an idea how to do it using JavaScript, but i am new in CRM, so someone else might appear with that type of solution, I would also be glad to read it.
The easiest solution I can think of would be to poll the value by adding a new handler to entity A's form OnLoad event.
The code would then employ setTimeout to constantly read the value of the field from the REST API, compare the content of the field, and if it's changed it would invoke Xrm.Page.data.refresh to asynchronously reload the form without a full page reload.
Another (IMHO better) option: upgrade to a more recent version. Starting in 2015 Update 1, subgrids have OnLoad event too: you just need to handle that, invoking Xrm.Page.data.refresh without the weight of repeatedly pinging the server.

Programmatically firing a client-side event

I have a typical ASP.NET web form application. It has about 20 separate user controls (.ascx files), each one containing a DetailsView control. One of the requirements of this application is that there needs to be a single Edit, Update, and Cancel link outside of those user-controls, which, when clicked, will cause each of those DetailsView objects to go into the correct mode, Edit or ReadOnly, and, if Update was clicked, do an appropriate database update. In other words, clicking that "global" link has to programmatically fire the client-side click for each of those corresponding links that you get "for free" when you create a DetailsView or GridView. I've tried copying the actual __doPostBack event that gets invoked when you do use one of those "internal" links, assigning it to a string, doing a Page.ClientScript.RegisterScriptBlock, then doing a LinkName.Attributes.Add("onclick", "script_string_name") -- but I just can't get it to work. What is the correct way to accomplish this?
You can use the asp:linkbutton control to do this.

Select all and none on items list , in knockoutjs

I am trying to implement a list of items that each have a checkbox to select the item. On top of the list, there is 2 radio button to check all or none items. However, when I update the selected list, the checkbox is not checked. I have got a fiddle here to illustrate the problem:
http://jsfiddle.net/hawaii/VcZBf/2/
Could you guys help me on this please.
Thanks
UPDATED
So you want to do a "checkAll(On this Page)" implementation.
To maintain changes to your checks from one paging event to the next, I would push the currently checked items in the grid to the server during the paging event, or have the act of checking / unchecking maintain back to the DB right after each event. Its a cheap call, and you aren't at a risk of losing checked items because the user hit the backspace key accidentally.
Without sending the checks to the server on every paging operation...
your checks to be stored locally separate from the list even when the template that those records represent is paged to another page.
(make sure to only update the people observablearray when you get your next page)
then, importantly, on every page event you need to apply the checks back onto the grid for the shown items.
Finally, to aleviate the fact that the checkmarks arent representing their checked state (you click check-all, and you don't see them get checked). This is because you had checked:$parent.checkedPeople. which will never work, since checkedPeople is an array, not a boolean. I changed this to a function that asks if this person ID is in the checked People array
anyhow.. here it is: http://jsfiddle.net/VcZBf/24/
Its a rough concept.
WITH sending the current checks to the server on every paging operation
Each object now would have an "isChecked" observable.
On every paging event, the current page's checkmarks are persisted to the DB server side.
Then if you page back to a page with checkmarks on it, they show back up for you.
Much smoother.
reference from previous answer:
http://en.wikipedia.org/wiki/Principle_of_least_astonishment
I simplified your structure a little bit. I don't think having both people and checkedPeople was really knockout-y. If you do want checkedPeople, it can probably just be a read-only computed observable.
I added an IsChecked field to the initial people (all false). I then changed the checkboxes to map to that. Finally, I had the radio buttons change all IsChecked fields using arrayForEach.
Right now, the radio button GUI isn't really intuitive. You can take two appraoches:
Make them regular buttons (recommended)
Make them check and uncheck automatically by data-binding the checked to a computed allChecked flag in the model. This would mean they check automatically even if you check the boxes one by one.
I also took out your logging. I'm assuming that was debugging, but you can re-add it if needed.

Adding a new row to a dynamic ASP.NET Table Control, at position x - Problems with Viewstate after postback

I am creating a dynamic table control with ASP.NET/C# and the table is being used to hold a form. I need to allow users to click on a button in a row and make a duplicate of that row right below the original. My page is also using AJAX and jQuery.
I have tried to use Table.Rows.AddAt(indexoforigrow+1, newrow) but I get an error that the index is out of the range of values. I figured maybe I wasn't getting the original row's index correctly so I just tossed in a 1 and still got the error.
I also noticed that when I press the button to execute the code, the table disappears. Any ideas on how to fix that?
I am thinking that if I am unable to get these issues fixed I will have to loop through the table and submit the data to a temp table, adding a new row where indicated. Then I would pull all of the data back out and display again.
EDIT
I moved on when I could not get this working and tried to setup my submit functions to loop through the data and submit it to a db and realized that I am experiencing the same issues when clicking the submit button as when I click the add row button. It appears that my issue is really with viewstates/postback.
I did some reading on this and from what I can tell the solution is to re-create the dynamic control on page load every time. But I am confused about how I can do this if I have no idea how many rows/cells I have and how is the information the user entered kept in the form? I have no way of saving the information to a DB or anything because as soon as submit is clicked it all disappears.
Have you considered using a different control? One of the grid controls might better serve your purpose.
I've handled situations (that sound) similar to what you're describing by using the footer of a GridView (among other ways). The big trick is to bind the display object (Table, GridView, etc.) to a list of objects. Then you manipulate the list of objects, rebinding the display object after the list has changed.
You will need to persist this list in some manner, or you could wind up with the list being reset to null. One way would be to save it as part of the session.
At any rate, the idea is to have a display object (GridView) bound to a list of objects. When the user clicks 'add', an item is added to the list. Save the list, then call the GridView.DataBind method.
You are on the right track with re-creating the dynamic table each time the page loads. I have dome similar things and my solution was to keep a client state in a hidden field on the page. Every time you add a row to the table on the client, increment a counter or adjust the state data in the hidden field. Then, on the server-when the page posts back, read from that hidden field to know how many rows were added on the client. You will have to use some kind of naming convention for the new rows you add(and the widgets in them) so you can re-create them on the server.
A simpler option may be to use an UpdatePanel. Rather than try to add the rows on the client, your "add row" button would cause a partial update. The server side code would add the new row to the table and the viewstate would be updated.
I ended getting my data guy to do a bit more processing on his end so that I could just bind a ListView to a sproc. Solved a few of my problems.
Thanks for the helpful comments.
Just returning to this almost a year later because I faced a similar issue in my current project. I was doing a few things wrong my first time around. First, I did indeed need to recreate the controls every load, but I also had to create them earlier in the page cycle. I was trying to create them during page load, which is after the viewstate is loaded.
The controls need to be recreated with the same ID before viewstate is loaded. I went with page init and it worked fine.

Categories