Ok, let me try to clearly explain what I'm attempting to accomplish here.
Basically, I have a site that is using a liberal dose of jquery to retrieve partialviews into a consolidated 'single view'. So far so good - it all works great and is very performant.
However, I would like to have the ability to 'flag' (using a button) any such set and as a consequence of flagging it, add it to a functional area that I have dubbed 'active-tasks'. What I'd like to do is to be able to then goto that 'active-tasks' panel and see a range of ui tabs that represented the consolidated views that I had added. Clicking on any tab would then re-invoke that consolodated view afresh with the parameters that had been used at the time of flagging it. This would therefore mean that I'd have to store the parameters (?) for creating that consolidated view, rather than the generated html (this part i can do at the moment).
So, any thoughts on how to elegantly store the code required to generate the consolidated view on clicking a tab button - no pressure :)
cheers - jim
Actually, after a minimal amount of research, it looks like the newly updated .data() jquery method (with the ability to add an object to the payload) may work for the above.
http://api.jquery.com/data/
basically, this allows you to add hash type keyed data to an id element for use later, so in my scenario above i could simply attach the parameters required to invoke the action method that related to my consolidated view on the tab.
I'll let you know how i progress with this...
jim
Related
I'm not sure about how to ask my question, so I'll show my screen.
I have a control for subscriptions in a page. The context of the page inst to post data, so the model is some kind of "read-only". My model has the inscriptions (left site), the inviteds (second tab of left side) and the approveds (right side). The green buttons, turn the current item as approved (send it to right side by ajax, removing the html from the left panel and inserting in the right panel). The red buttons (remover) do the opposite, unapproving the user.
Ok, until now I was just trying to explaining the picture. Now, my real problem.
Every m is a button. It opens a messagebox like the 2nd item on the right panel shows. The m turn into ^ to close the accordion.*
My problem is: I'm using a Ajax.BeginForm in those textarea + submit button but without model binder. I'm using
#Html.TextArea("message")
instead
#Html.TextAreaFor(m=>m.Message)
because my view model, like a said before, has another context. Now, I really dont know the right approach to do that. I want the jquery validation unobstrusive to work with this textarea. I was thinking about use a #Html.RenderAction for each partial with messagebox, but I'm worried about performance. There is any kind of help me with that?
Doesnt matter if takes longer, I'm looking for the right stuff.
Thanks
*the + sign, m and ^ will be changed by nice icons later.
If the model for this page has another context make up another page with the right context and let it pop up in an iframe...
From your screenshot I would assume that this is about programming of the last 10%. The concept of approval has a 'lesser-reject-nature': People that give away something for approval typically try to follow the rules to allow a fluent approval. As soon as you articulate the approval rules clearly any need to respond with messages becomes a minor issue.
"because my view model, like a said before, has another context..."
You're in control of the view model? Why not arrange it so it properly fits the view, and map your data to it. Then you would be able to use the strong typed html helper.
Otherwise, consider rendering a partial view. You can then redefine the #model type for the partial, it could be a property of you main view's model, and use the Html helper on that.
I am having the exact same problem described here. Unfortunately because I don't have 50 points yet I can't comment on it so I have to create a new duplicate question.
I mean it's not "100% EXACTLY" like the other guy's problem because for me the problem exists on the Edit Form and I'm using a combination of custom forms and fields. But I am adding the custom save event handler at the field level per suggestion #2 made by the guy at this site. I should also note that when I create a new Document Library without any custom forms or Content Types and just use my custom fields straight-up, the event handler also does not fire. If however I create a new regular SharePoint list and add the custom fields then the OnSaveHandler DOES fire! I So I'm not quite sure why it doesn't work in Document Libraries but it does work in lists because I was under the impression that the beauty of custom fields was that they operate independently of everything else. Meaning, even if I was doing something wonky with my Edit Form or some other control, since I am attaching my custom method to the SPContext.Current.FormContext.OnSaveHandler in the OnInit method of my custom field then that should fire no matter what! Even when the field is being loaded for the first time I actually see the event being wired up in the debugger. In debug mode I have a breakpoint next to the "if" statement below and it hits that breakpoint which means that when the FormContext.OnSaveHandler is triggered my method should fire.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if ((SPContext.Current.FormContext.FormMode == SPControlMode.New) || (SPContext.Current.FormContext.FormMode == SPControlMode.Edit))
SPContext.Current.FormContext.OnSaveHandler += new EventHandler(MyHandler);
}
Any thoughts? Suggestions?
Thanks!
UPDATE #1: After a little troubleshooting I was able to deduce that the EventHandler in my custom field was being fired but ONLY when used in regular lists and NOT Document Libraries! In regular SharePoint lists not only is the SPContext.Current.FormContext.OnSaveHandler being fired but the values from the custom fields are being saved as well.
As a side note, when saving the data back to my custom field that inherits from SPFieldText, the value (which is json data) displays in the list view as #VALUE!, which I think is kind of weird. I mean it's able to read the json data that's stored in the field correctly because it shows up in the Edit Form just fine. But for some reason SharePoint just displays it as #VALUE! in the list view.
So after many frustrating hours it looks like there are several issues that arise when using custom fields in a Document Library.
You can't use them in any meaningful way and expect the data to be saved when using a custom upload page. In other words, if you want to create your own custom upload page that combines the file upload input field and browse button along with your own custom fields embedded in a ListFieldIterator then the values WILL NOT BE SAVED. This is a fact! The reason is that the operation for uploading the file and creating the initial ListItem along with generating it's ID value occurs ASYNCHRONOUSLY with respect to the ListItem EventReceiver. So what does this mean exactly? It means that when you try to access the values stored in your custom field(s) in the SPItemEventProperties parameter of the ItemAdded method in the ListItem's Event Receiver all of those values will be null since the current SPContext is completely unaware of the existence of those fields and their respective values because all of the events that occur with respect to the initial document upload are executed in a different thread...asynchronously. Conversely, when the custom fields attempt to "save themselves" back to the newly uploaded document the SPField.ListItem's document ID is still set to zero because these custom fields are...you guessed it, executing in a different thread and are not "in synch" with the upload event that took place which generated the new document ID. Although I've read about a few different workarounds regarding this issue, none of them seem to work, or they are very convoluted or require you to abandon using custom fields which isn't really a workaround but more of a "throwing in the towel". One suggestion was to simply update the Elements.xml file for the EventReceiver by simply adding a "Synchronous" entry to force the event to occur synchronously instead of asynchronously. At first I thought this was too easy and too good to be true. As it turns out, I was right. :)
You can't nest a custom ListFieldIterator inside a custom control and expect your custom fields to save the data that they contain. You MUST use the ListFieldIterator directly in your form template. Period! If you try and wrap the ListFieldIterator with your custom fields in a custom control you will be very frustrated with the results.
As a side note, once the document has been uploaded and an ID has been created, you CAN enter data into your custom fields in the Edit Form and the values WILL be saved because now your code will actually be able to reference the ListItem's ID value since the ListItem will already exist in the list. Again, this is contrary to a custom upload form where the ID for the ListItem does not yet exist because you haven't actually uploaded the document yet.
I REALLY wish that Microsoft would provide some sort of update that would allow developers to get around this issue with Document Libraries and I think that it's pretty clear that they knew this was an issue when they first released SharePoint which is why the default behavior for the Document Library "New Form" is to present the user with a standalone Upload form which then redirects the user to the Edit Form so that they could avoid all of this. Of course this leaves developers who wish to allow users to upload a document and enter data on the same screen without a leg to stand on when using custom fields. Your only alternative is to use custom forms and programmatically set all of the field values and add in tons and tons of conditional logic for every single permutation of all the different fields and layout possibilities but that's a whole other animal and certainly defeats the whole reason why Microsoft created the concept of custom fields in the first place!
I am working on an MVC2 project, on a view we display a large data set which refreshes every minute with latest data..some specific records are updated every minute in this data set. I want the browser to focus on these specific records..Not sure how to use javascript focus() here dynamically...
any clue?
thanks,
You need to provide more detail as to exactly what you are attempting to do.
If you are attempting to focus just ensure each record has a unique identifier then you can focus on individual records.
Alternatively you could simply keep the focus at the top or bottom of wherever you are displaying them.
EDIT:
In that case I would suggest something like the following
var currEle = document.getElementById("Record123");
currEle.focus();
Suppose you know how to issue an Ajax call and return either partial view or JSON data and how to use that data on the client afterwards...
You can only focus to a point in the document when
there's only one change or
all changes are summarised together in the same document area
We're also not talking about focusing as in document perspective, but rather about focusing of users attention to document specific content (or part of it).
First option
You can always use something like jQuery.scrollintoview() plugin (link to blog post that describes the plugin here) that will scroll document to the record that changed and highlight it using jQuery UI effect highlight. Linked blog post also describes the purpose of visual animated scrolling instead of simple jumping within the document.
Second option
Put changes at the top and keep your document scrolled at the top when content gets updated. You can blink a few times some icon informing the user of the changed content in the changes area.
My plan is to create a a two-pane page using ASP MVC 3. The left pane should be a small filter pane and the right the main content, showing a list of objects (say products).
Initially all products will be shown since no filter is applied. When selecting "only red", only red products are shown in the list. When further selecting a price range, only products in that price range will be shown.
Functionally the plan is to implement the filtering pane as a treeview with checkboxes (to be able to drill down to more and more specific filtering options), graphically it will probably be enhanced in some way to improve usability.
What is the best way to implement the coupling between the filter pane and the main list? Everything should work server side, but should of course use javascript (jQuery) when possible for direct feedback.
The simplest way is probably to make it closely coupled solution, calling a specific Asp MVC action using a custom-built javascript (with fallback to a form post). Doable enough, sure, but how to make the solution reusable? Also it would be nice to not loose all filtering data when navigating forward and back, i suppose GET arguments is the only decent way to do that?
Are there any best practices, any guidelines or anything to base this on to make a nice modular structure for filtering.
Victor, I recently had to solved this same problem. I'm not promising it's the best way but it's pretty clear and should even work well in case JavaScript is disabled (who even does that anymore?).
Create a that calls the action with all the field-selectable search options like "only red".
To that same form, add empty, hidden value for the things not directly as fields (paging, sorting...)
Setup your form with the excellent and very easy to use JQuery.Forms (http://www.malsup.com/jquery/form/) to make you form submit via JQuery (all your form values will be passed as JSON on form submit).
Make your back/next/paging/sorting links pass their individual values via query (no-JS fallback) and use JQuery to capture their click events. The JQuery click events on those links should assign the value of the value passed by the link (page number, sort column name...) to the corresponding hidden field in the form and call submit (with thanks to Jquery.Forms will submit via AJAX).
When you configure JQuery.Forms, you can define a callback method. In the callback method take the result (the HTML returned by your action that should contained your filtered+sorted+paged result) and replace the document (or DIV if you used a partial action + view) with that.
The result is a JQuery solution that works when JS is off. You also have very minimal JS code to write other than wiring the event handlers.
I'm not sure if it will be helpful but in MVC 3 you have access to a property called IsAjax from the view so you can do specific things to server a slightly different view when called from AJAX.
Cheers
i have a form that is generated dynamically.
the plan is to generate it, the user to enter data, and then to save all that lot away.
although a slight variation to this is if the form has previous data associated with it, and then it loads in all pre-populated. - the user may then change any previous selections.
and that is the rub really, i know if i call generateform regardless of postback the viewstate should take over and remember what the settings weer.. but as the generateform method as mentioned above populates the form if the form has previously been saved. which will win, the viewstate or the generateform method for the field populations.. ?
thanks
nat
If you dynamically generate any form controls that post data or cause a postback, you need to recreate them again on postback in order for them to be bound to their data, or their events, after the postback. Conceptually, this makes sense. If you don't have a control in your form after the postback, how could you look at its contents?
There are several ways you could approach this problem.
1) Call GenerateForm() no matter what. Since you said it pre-populates some of the data, you would need to change it so it can be called without doing that. ASP.NET will populate the controls with the data posted automatically on postback, which is what you want.
2) Keep a list of all your dynamically generated controls in a ViewState variable, so you can re-generate them upon postback. For most situations involving dynamically-created controls that aren't very simple (e.g., you may not know in advance exactly what controls are generated), this is the best solution. And often you will want to be able to access the data after a postback, but maybe you really don't want to recreate the whole form because you aren't using it any more.
As long as you recreate a control of the same type and ID on or before Page_Load(), it will be bound to the posted data. It does not need to be in exactly the same place on your form. And it does not need to be used or displayed, either - you can destroy it before the form is rendered, e.g., in Page_PreRender()
3) If you have no interest in any of this, you can always use Request.Form to look directly at the posted data, though this can also be tricky because the names will likely not match your form control IDs exactly. ASP.NET generates unique client-side IDs that depend on the container, and this is what you'll find in Request.Form. If you don't regenerate a control, you may not be able to easily determine the ID that you are looking for. Generally, you should not do this, but it's a way to look at the posted data and sometimes you need it.