Cocoa-Binding : Submit changes manually? - cocoa

in my application I have a NSTableView bound to an ArrayController (arrangedObjects). I also have a Details-View (just some textfields) bound to the same Controller (selection).
Now every time I edit a textfield the changes are automatically send to the ArrayController and the Table changes as well. How can I avoid this? What I want is a "Submit-Button". Changes on the data should only be send to the controller when I press the button and not automatically every time I do an edit.

There are really two answers to this question. The first is more philosophical: in most cases you want updates to the model to occur instantaneously. For the most part users shouldn't have to be bothered with saving, committing, etc. changes the make. Binding's pervasive integration with the NSUndoManager means that anything the user does can be undone (or should be undoable). All user actions should be "low risk" such that making a change and then undoing does not cause unnecessary "harm" to the user's data or the application state. If you're using Core Data for your model layer, you can always roll-back or save a set of changes programmatically using the NSManagedObjectContext's methods. Unless there's a really good reason why the user needs a "Submit" button, don't put one in. In line with this philosophy is Gmail's "Undo Send" functionality. Even sending an email should be undoable (within reason).
The second answer is more practical. Of course there are situations where you're dealing with a backend system that isn't as forgiving of undos as Cocoa. In that case, the best option is to create a temporary model object that serves as the model for the UI (think a View-Model in the Model-View-View-Model (MVVM) architectore). When the user submits the changes, you can copy the temporary model object into the persistent model. In Core Data, you can use an in-memory persistent store backing a separate managed object context to hold these temporary instances and then merge changes from this temporary context into your main context on submit.

This might be enough:
Select the text fields in Interface Builder.
Switch to the "Text Field Attributes" pane of the Inspector panel (hit Cmd-1).
Change the Action popup box to "Sent On Enter Only".

Related

How do I restore the model when user clicks "Cancel" in a sheet?

I have a sheet with some editing fields in it, each bound to an attribute in my model, for editing.
Thus, the model is directly modified as the user makes changes in the sheet.
How should I restore the model if the user clicks "Cancel" on the sheet?
In my research I think I've seen people using NSUndoManager for this, but I'm not eager for that level of complexity at this stage if I can avoid it.
Or have I architected this wrong in a more fundamental way?
I'm using storyboards and aiming for 10.10+, if that's relevant.

MVC - who decides what to do if there was no content?

When loading a page that lists for example events from a DB, but there are no events going on right now, who's decision should it be to show a message "sorry no events going on right now..."?
Should the model check if the array with events is empty, and call the view that holds this message as static content
Or should the view check if the array with content is empty, and if so display a message that informs the user?
Or is this opinion based and it depends on personal preference?
If it is based on personal preference, what are some of the advantages and disadvantages of either method?
EDIT:
The same question could be applied to: We are trying to load an event, but the event is over, so it will say "sorry, this event is already over". Again: Model's choice or View's choice to say this?
View is the part of triad, which will be aware that there is no content, when said view request the list of active events from model layer and gets back nothing.
If you are looking at this in the context of PHP, then your view won't be observing the model layer and will have to initiate the request for data.
Also, if you actually send back completely nothing, then the same view should also set the response code to 204.
When to show which kind of message is obviously a choice of the view. The model shoudln't know anything about users reading messages but only about its inner state.
The actual question is, how does the view know when to decide about which message should be shown. There are mainly two ways I could think of:
The view polls the state of the model each minute/second/millisecond/when-user-clicks-button/whatever and updates the messages if needed
or
The model itself emits events when its state changes and the view listens to those events.
But, the model emitting an event saying "my state is changed" is something totally different from deciding to show a message to the user and both should be strictly seperated.

Cocoa MVC: interaction between "model controller" and "view controller"

Just started learning Objective-C and Cocoa with the help of BNR's Cocoa Programming for Mac OS X (4th Ed.), and I'm working on a document-based application. I've read through Apple's developer documentation on the document architecture, and have chosen to subclass NSWindowController and override makeWindowControllers on my NSDocument subclass. I have a few reasons for doing this:
to separate model logic (in NSDocument subclass) from view logic (in NSWindowController subclass).
to customize the title of my document windows (Apple's developer documentation says that the proper way to do this without unwanted side effects is to subclass NSWindowController and override windowTitleForDocumentDisplayName:
Apple's documentation seems to strongly suggest subclassing NSWindowController for all but the simplest of applications, and mine is definitely not "simple"
So, my NSDocument subclass is a model controller, and my NSWindowController subclass is a view controller. Further, I understand that most of an application's "work" is done in the controller objects, as the views and models should be as application-agnostic and reusable as possible. Now comes my question: how do these two types of controllers interact to actually do this "work"?
For example, imagine I'm writing a spreadsheet application, and I want to have a menu item (or toolbar button) that brings up a sheet for creating a chart or graph from some of my data. In that sheet, the user will enter various parameters and options for how to create the chart or graph, then click "OK" (or whatever the button is called).
Who should respond to the menu item's action, the document (model controller) or the window controller (view controller)? The task of actually loading and showing the sheet seems decidedly "view-related", so it should go in the window controller, correct? But the controller for the sheet needs a model to display to the user (a Chart object, or maybe ChartInputs); where does that model get created and given to the sheet controller? Should the document respond to the menu item by creating the ChartInputs model object, then pass that to the window controller, which creates the sheet controller, passing it the model object, and shows the sheet? Or should the window controller respond to the menu item, request a new model object (perhaps through some sort of factory provided via dependency injection into the constructor of the window controller), then proceed with creating the sheet controller, passing the model, and showing the sheet?
What about after the user fills out the sheet and clicks "OK"? Where should control be returned to process the user's choices and actually create the chart -- window controller, document, or both? What about logic to validate the user's inputs after they click "OK", but before the sheet is dismissed (in case something is invalid)?
To begin, consider windowless operation of your NSDocument. For example, you might create a utility application which shares your NSDocument class, opening documents for scripting, printing, or other manipulation, but without presenting your primary document window. Imagine your NSDocument class reused for that application – and put the logic you wouldn't want into your window controller. This way, the NSDocument subclass is primarily responsible for activities which affect the document's state.
These are the responsibilities of the model-controller (NSDocument subclass):
Serialization and deserialization
Loading and saving
Manipulating the document's state
Managing and dispatching print views
Monitoring the document for changes by others
Refreshing supporting data sources – sources which affect the document model – and applying changes to the model and document as needed
Managing an activity log related to the document
Owning the undo manager
Exposing the essential model objects to the view controller
Creating window controllers
Facilitating some editing behaviors, such as a change to one property triggering creation or removal of objects
If you're using Core Data, your managed object context, persistent store coordinator, and persistent store are part of the model-controller, not the model. Of course the managed objects themselves are part of the model.
This leaves these responsibilities to the model:
Helper methods for inserting, rearranging, and deleting model objects
Helper methods for accessing specific parts of the model
Data validation
Rendering the model to strings, in various formats
Serializing and deserializing oneself
Facilitating some editing behaviors, such as a change to one property triggering changes to other properties
On the other side, these are the responsibilities of the view-controller:
Manipulating the view to keep it in sync with the model
Manipulating the view to keep it in sync with the document state
Responding to localized actions, such as a button which adds or removes a model object
Presenting auxiliary views and responding to input in those views
Dispatching actions which are affected by selections in the UI, such as the selected rows in a table view
Managing auxiliary controllers used during editing, which are not related to the document itself (such as web-service data)
Serving as a data source for view objects
If you're using Cocoa Bindings, your bindings also part of the view controller.
This design produces a reasonable separation of responsibilities between the view-controller and model-controller. However, they both sit between the view and model. While this produces modularity it doesn't produce decoupling.
Though I did consider windowless operation, I largely arrived at this design pattern empirically – by placing similar code together and separating code that felt out-of-place. I'm curious if others post authoritative sources or references which agree or disagree about how to do this.
To take up your example, I'd suggest this design:
EditorWindowController creates ChartParameters object and gives it a reference to the document's model:
[[ChartParameters alloc] initWithWorkbook:self.document.workbook]
EditorWindowController sets up the new-chart view, which probably has its own NewChartViewController. It passes the ChartParameters and document objects to the NewChartViewController and displays the window.
The ChartParameters object is responsible for validating the user's choices. The NewChartViewController needs to manipulate the view to keep it in sync with the validation result. (Avoid letting the user make a mistake: don't wait until the end to validate the input.)
When the view finishes, the NewChartViewController asks the model to create a new chart using the given parameters:
[self.document.workbook addChartWithParameters:self.chartParameters]
If you want the not-yet-a-chart object to be part of your document, you can do is this way instead:
EditorWindowController asks document model to create a new chart object:
Chart *newChart = [self.document.workbook addChart]
Thew new chart should have a flag set, indicating it's not ready for display.
EditorWindowController sets up the NewChartViewController, passes it the chart, displays the window.
Chart object validates the users's choices and the NewChartViewController keeps the view in sync.
When finished, tell the chart it's ready for display. Or if the user cancels, remove it.
In either of these designs, NewChartViewController is a model-controller and view-controller in one, localized for its particular task.

Django delayed updates to database

I'm creating a Django/JQuery/MySQL application where I pass a composite data structure 'grid' as
return render_to_response('products.html', grid)
I render 'grid' into a set of UI elements ('td', 'button', 'div' etc. encapsulated in a HTML 'table'.
A typical use case:
User clicks on a certain UI element in the table
jQUery.click() is called which creates a inner 'input' tag for the clicked element.
User can add/modify/delete text from the element.
When focus is lost, jQuery.blur() is called which reverts the original properties of the clicked element such as removing input tag etc.
jQuery.blur() also calls a AJAX function where I do a .post call to send in user modified data back to a URL (function in view).
The called function in view then commits the new changes in database and returns a 'success' event back to web page:
tc_model_instance.update(tc_id=json_data['id'])
Through this use case, as you can see the changes are immediately committed to the database as soon as user eneters data and gives up focus on a particular element. Without using DB transactions in INNODB, how do I go about creating a View-Template association such that any changes in HTML template are asynchronously reflected in the model, but not necessarily written into the database.
A related question:
If possible I'd also like to create a event based bi-directional association between rendered template and my data structures as part of the view in such a way that any changes made either in web browser's UI element or associated view's data are always in sync. I plan to use AJAX for the most purpose. Not sure if forms would make sense in this regard.
Thanks.
You could probably throw a copy of the object into the session map and all posts alter that object instead of the DB directly. Then when the user presses a save button you'd fire off another POST command to the server that would then just call session['my_object'].save().
Note though that the session object is also saved in the DB, so if you are trying to avoid hitting the DB totally what I wrote above wouldn't help.

What kind of events should be created for a CRUD application?

I have an application that is centered around a database (ORM is LINQ-SQL) that has a table called Assignment. I am using the repository pattern to manipulate the database. My application is basically going to perform CRUD operations. I am new to delegates and events and I am asking you what events I should create (like maybe AssignmentCreating, AssignmentCreated) and what kind of delegate to use (like maybe a custom delegate or just an EventHandler)? UPDATE: My application has a ListView with some columns that show some data. On the right side, I have a panel with textboxes binded to the values of the currently selected assignment. Like a textbox for Score, one for title, etc. and they are all editable. That deals with the Read and Update. Then I have a custom dialog box that has the same kinds of textboxes, and the dialog Creates new assignments. Then users can just select an assignment and Delete it via the Delete button, or a context menu.

Resources