I write a component in joomla 2.5. I want a view use multiple model on view.
I saw Multiple models for a view without controllers.
My code:
In class controller (Controller.php)
public function display($cachable = false, $urlparams = false)
{
AppHelper::addSubmenu(JRequest::getCmd('view', 'apps'));
JRequest::setVar('view', JRequest::getCmd('view', 'apps'));
$model = $this->getModel('app'); // get first model
$view = $this->getView('apps', 'html'); // get view we want to use
$view->setModel($model, true); // true is for the default model
$vermodel = &$this->getModel('version'); // get second model
$this->assignRef('version', $vermodel);
$view->setModel($vermodel);
var_dump($this);
parent::display($cachable);
return $this;
}
In class view (view.html.php)
public function display($tpl = null)
{
// Initialiase variables.
$this->form = $this->get('Form');
$this->item = $this->get('Item');
$this->state = $this->get('State');
$this->form2 = $this->get('Form', 'version');
// var_dump($this->form2);
}
But, view can't display to form!!!
Help me!! Thank you all.
Insteed of:
$this->form2 = $this->get('Form', 'version');
You should use:
$this->form2 = $this->getForm();
For me it works. I suppose there is only one default model, thats why we should call model's function other way.
Related
if I provide the data query as properties of the CMSRepeater, the repeater shows all items (published or not) in preview mode and only published items on the live site.
However, if I try to pass a datasource to the repeater, I can't get it to do the same thing.
Is there some property or method I'm missing?
Works
<cms:CMSRepeater ID="rep2" runat="server" EnableViewState="true"
Path="./%" OrderBy="NodeOrder ASC"
MaxRelativeLevel="1"
ClassNames="MyClassName"
SelectedColumns="Col1, col2, etc">
</cms:CMSRepeater>
Does Not Work
private DataSet LoadRepeaterItemsWithoutCache()
{
var columns = #"col1,col2";
var path ="./%";
TreeProvider tree = new TreeProvider();
return tree.SelectNodes("MyClassName")
.OnCurrentSite()
.Path(path)
.OrderBy("NodeOrder")
.NestingLevel(1)
//.Published(true/false)
//.CheckPermissions(true/false)
.CombineWithDefaultCulture(false)
.Columns(columns);
}
var tnds = LoadRepeaterItemsWithoutCache();
rep2.DataBindByDefault = false;
rep2.HideControlForZeroRows = true;
if (!DataHelper.DataSourceIsEmpty(tnds))
{
rep2.DataSource = tnds;
rep2.DataBind();
}
Looks like you need to modify your query a bit. Your function is expecting a DataSet as a return value and you're returning an ObjectQuery. If you want or need to return a DataSet then add .Result to the end of your .SelectNodes() method.
.Columns(columns).Result;
The other option is to return an ObjectQuery and simply assign that to the repeater and let the natural lifecycle process things.
public override void OnContentLoaded()
{
//rep2.DataBindByDefault = false;
rep2.HideControlForZeroRows = true;
TreeProvider tree = new TreeProvider();
rep2.DataSource = tree.SelectNodes("MyClassName")
.OnCurrentSite()
.Path(path)
.OrderBy("NodeOrder")
.NestingLevel(1)
//.Published(true/false)
//.CheckPermissions(true/false)
.CombineWithDefaultCulture(false)
.Columns(columns);
}
I think you can try this way:
private DataSet LoadRepeaterItemsWithoutCache()
{
var columns = #"col1,col2";
var path ="./%";
TreeProvider tree = new TreeProvider();
var datasource = tree.SelectNodes("MyClassName")
.OnCurrentSite()
.Path(path)
.OrderBy("NodeOrder")
.NestingLevel(1)
//.Published(true/false)
//.CheckPermissions(true/false)
.CombineWithDefaultCulture(false)
.Columns(columns);
//If is in LiveSite mode, then return only published
if (PortalContext.ViewMode == ViewModeEnum.LiveSite)
datasource = datasource.Published();
return datasource;
}
Before return the datasource, check if the site is in LiveSite mode. If true return only the Published nodes, otherwise return Published and Unpublished nodes.
I've not tested it, but hope it works.
I wanted to check if the productDiscount entity is already exist in the database, if it is exist then I wanted to update it. But instead of updating the entity the following code adds a new one. How to solve this problem..
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ProductDiscount(ProductDiscount productDiscount)
{
if (!ModelState.IsValid)
{
var viewModel = new ViewModelProductDiscount()
{
Products = _context.Products.ToList()
};
return View(viewModel);
}
var id = productDiscount.ProductId;
var disInDb = _context.ProductDiscounts.FirstOrDefault(p => p.ProductId == id);
if (disInDb==null)
{
_context.ProductDiscounts.Add(productDiscount);
_context.SaveChanges();
}
else
{
_context.ProductDiscounts.Add(disInDb);
_context.SaveChanges();
return Content(disInDb.Id.ToString());
}
return RedirectToAction("Products");
}
from the else block remove _context.ProductDiscounts.Add(disInDb); Just map the productDiscount values into disInDb and then _context.SaveChanges();
Like
else
{
disInDb.Name = productDiscount.Name;
disInDb.Discription = productDiscount.Discription;
_context.SaveChanges();
}
I don't really know how your ProductDiscount object looks like so I will assume your object props but it should give you an idea of how to update the record. Inside your else this line _context.ProductDiscounts.Add(disInDb); is what is causing the issue. Instead you want to do the following inside the else block
else
{
disInDb.DiscountCode = "somecode"; //change this to the correct prop name which needs updating
disInDb.DiscountProductName = "somename"; //change this to the correct prop name which needs updating
_context.SaveChanges();
}
I have created a model and added the $has_many for selecting multiple products. This is working fine but I am unable to make the selected products sortable by drag and drop. I know this is possible I have seen it. But I am unable to find anything in the documentation that shows how to get this done. Here is my model:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(FUEL_PATH.'models/Base_module_model.php');
/**
* This model handles setting up the form fields for our contact form
*
*/
class Products_category_model extends Base_module_model {
public $required = array('name', 'published');
public $has_many = array('products' => array(FUEL_FOLDER => 'Products_model'));
function __construct()
{
parent::__construct('w_product_categories');
}
/*
This will provide the list of records for display in the Admin Panel
Note how the "excerpt" will display, but truncated
Because we are using some MySQL functions in our select statement,
we pass FALSE in as the second parament to prevent CI auto escaping of fields
*/
function list_items($limit = null, $offset = null, $col = 'name', $order = 'asc', $just_count = false)
{
$this->db->select('id, name, published', FALSE);
$data = parent::list_items($limit, $offset, $col, $order);
return $data;
}
function form_fields($values = array(), $related = array())
{
$fields = parent::form_fields($values, $related);
return $fields;
}
}
class Product_category_model extends Base_module_record {
}
So it is very simple I discovered. I added this in the form fields function:
// Makes the has many drag and drop sortable.
$fields['products']['sorting'] = TRUE;
$fields['products']['after_html'] = "<div style=\"clear:both;font-style:italic\">NOTE: you can sort selected product to your choosing by clicking on the product and then dragging it into the desired placement in the list</div>";
Subject. I want init a new instance of model in it static method:
var Schema = new mongoose.Schema({...});
//...
Schema.statics.createInstance = function (name, pass) {
var newPerson = new Person; // <--- or 'this', or 'Schema'?
newPerson.name = name;
newPerson.pass = pass;
newPerson.save();
return newPerson;
}
// ...
module.exports = db.model("Person", Schema);
How I can do this?
You were on the right track; this is the Model the schema is registered as within a schema.statics method, so your code should change to:
Schema.statics.createInstance = function (name, pass) {
var newPerson = new this();
newPerson.name = name;
newPerson.pass = pass;
newPerson.save();
return newPerson;
}
And Leonid is right about handling the save callback, even if it's only to log errors.
You almost answered your question. The only problem with your code is that you don't have a registered model at this point. But you can use mongoose.model to fetch it dynamically:
Schema.statics.createInstance = function (name, pass) {
var newPerson = new db.model('Person'); // <- Fetch model "on the fly"
newPerson.name = name;
newPerson.pass = pass;
newPerson.save();
return newPerson;
}
Ow. And consider handling save callback. You can't be sure that save operation won't fail.
I have been working on making a Search using Solrnet which is working the way I want to. But I just would like some advice on the best way to pass my query parameters from my web page into Solrnet.
What I would ideally like to do is pass my query string parameters similar to how this site does it: http://www.watchfinder.co.uk/SearchResults.aspx?q=%3a&f_brand=Rolex&f_bracelets=Steel&f_movements=Automatic.
As you can see from the sites query string it looks like it is being passed into SolrNet directly. Here is I am doing it at the moment (facet query segment):
public class SoftwareSalesSearcher
{
public static SoftwareSalesSearchResults Facet()
{
ISolrOperations solr = SolrOperationsCache.GetSolrOperations(ConfigurationManager.AppSettings["SolrUrl"]);
//Iterate through querystring to get the required fields to query Solrnet
List queryCollection = new List();
foreach (string key in HttpContext.Current.Request.QueryString.Keys)
{
queryCollection.Add(new SolrQuery(String.Format("{0}:{1}", key, HttpContext.Current.Request.QueryString[key])));
}
var lessThan25 = new SolrQueryByRange("SoftwareSales", 0m, 25m);
var moreThan25 = new SolrQueryByRange("SoftwareSales", 26m, 50m);
var moreThan50 = new SolrQueryByRange("SoftwareSales", 51m, 75m);
var moreThan75 = new SolrQueryByRange("SoftwareSales", 76m, 100m);
QueryOptions options = new QueryOptions
{
Rows = 0,
Facet = new FacetParameters {
Queries = new[] { new SolrFacetQuery(lessThan25), new SolrFacetQuery(moreThan25), new SolrFacetQuery(moreThan50), new SolrFacetQuery(moreThan75) }
},
FilterQueries = queryCollection.ToArray()
};
var results = solr.Query(SolrQuery.All, options);
var searchResults = new SoftwareSalesSearchResults();
List softwareSalesInformation = new List();
foreach (var facet in results.FacetQueries)
{
if (facet.Value != 0)
{
SoftwareSalesFacetDetail salesItem = new SoftwareSalesFacetDetail();
salesItem.Price = facet.Key;
salesItem.Value = facet.Value;
softwareSalesInformation.Add(salesItem);
}
}
searchResults.Results = softwareSalesInformation;
searchResults.TotalResults = results.NumFound;
searchResults.QueryTime = results.Header.QTime;
return searchResults;
}
}
At the moment I can't seem to see how I can query all my results from my current code by add the following querystring: q=:.
I'm not sure what you mean by "parameters being passed into SolrNet directly". It seems that watchfinder is using some variant of the model binder included in the SolrNet sample app.
Also take a look at the controller in the sample app to see how the SolrNet parameters are built.